莫忘尘的收纳盒

人不能不痛不痒的活着


  • Startseite

  • Archiv

__Block浅谈

Veröffentlicht am 2018-01-21

常将有日思无日,
莫待无时思有时.

很多同学在面试中都有可能被问到__block的问题, 与__weak的比较,或者是其作用.__block都是配合block体使用的,目的是让block内部能修改外部变量的值.

举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- (void)testBlock
{
typedef void (^Block)(void);
__block int i = 10;
Block block = ^(){
NSLog(@"inner block 1 -- %d", i);
i = 20;
NSLog(@"inner block 2 -- %d", i);
};
i = 30;
block();
NSLog(@"outer block -- %d", i);
}

上述代码输出结果:

1
2
3
2018-01-21 15:43:03.378546+0800 Block[67824:5612019] inner block 1 -- 30
2018-01-21 15:43:03.378726+0800 Block[67824:5612019] inner block 2 -- 20
2018-01-21 15:43:03.378845+0800 Block[67824:5612019] outer block -- 20

根据输出结果,__block确实起到作用,使变量在block内部被重新赋值.
__block修饰符是如何起作用的,通过下面的例子,了解如何不使用__block关键字使block内部修改外部变量值,来理解block的作用过程.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- (void)testBlock_variant
{
typedef void (^Block)(void);
int i = 10;
int * i_block = &i; // 定义指针变量 i_block 指向 i 变量的地址
Block block = ^(){
NSLog(@"inner block 1 -- %d", * i_block); // * i_block 取地址的值
* i_block = 20; // 对 i_block对应地址的值进行修改
NSLog(@"inner block 2 -- %d", * i_block);
};
i = 30;
block();
NSLog(@"outer block -- %d", i);
}

上述代码输出结果:

1
2
3
2018-01-21 15:51:18.395184+0800 Block[67927:5624382] inner block 1 -- 30
2018-01-21 15:51:18.395344+0800 Block[67927:5624382] inner block 2 -- 20
2018-01-21 15:51:18.395448+0800 Block[67927:5624382] outer block -- 20

与__block修饰效果一致.

Demo下载地址 Block

如有疑问或错误,欢迎大家批评指正.

iOS NEHotspotHelper使用

Veröffentlicht am 2017-07-08

杀不死你的,终将使你变得更强大. –《小巨人》

一、简介

首先放上苹果官方文档:

1
https://developer.apple.com/reference/networkextension/nehotspothelper

NEHotspotHelper 是 NetworkExtension.framework 中与wifi连接相关的一个功能类。

  • + supportedNetworkInterfaces
    可以获取到当前扫描到的WIFI列表,包含SSID,加密方式,信号强度信息。
  • + registerWithOptions:queue:handler:
    注册当前app成为一个wifi辅助管理者,可以对指定的wifi,进行密码导入,并作字符串标记。

二、使用步骤

第一部分(权限申请)

1.向苹果官方邮箱发权限申请邮件,使用自己的开发者账号邮箱申请,即代表所在的开发团队申请

2.邮件内容需要简单介绍APP的使用场景,以及为什么要使用NEHotspotHelper。

3.发送完,就会收到一封苹果的回复,这时候去访问提示的那个网址,填写对应的权限申请信息。

4.访问https://developer.apple.com/contact/network-extension/,登入自己开发账号,会有自己和所在开发团队的信息

5.填写对应的App信息,然后send。

6.邮箱会收到信息确认邮件,核实一下刚才填写的信息。如果没问题,就等大约三周时间,等苹果官方回复。

7.我这次 6月15申请,7月1号收到申请通过的邮件

8.去开发者中心配置开发证书,把Wireless Accessory Configuration,iCloud配置进去。
注意:配置文件,必须新建,在之前已存在的修改,后面工程运行会提示证书权限不匹配。

第二部分(项目工程配置)

1.Target - Capabilities 开启iCloud

2.开启Wireless Accessory Configuration

3.上述步骤完成,工程会自动生成一个 .entitlements 权限文件,需要手动添加一项:com.apple.developer.networking.HotspotHelper ,设置它的Bool值为YES

3.在项目中配置info.plist文件
UIBackgroundModels 数组中增加 network-authentication

4.使用NEHotspotHelper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// wifiArray是含有wifi SSID和密码信息的数组
- (void)settingSSID:(NSArray *)wifiArray
{
if (!IOS9) {
return ;
}
// 此处设置的内容会在WiFi列表中每个WiFi下边展示出来
NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:@"🔑WiFi一键连接",kNEHotspotHelperOptionDisplayName, nil];
//线程
dispatch_queue_t queue = dispatch_queue_create("com.testcompany.wifi", 0);
//注册HotspotHelper,returnType为YES才说明可用
BOOL returnType = [NEHotspotHelper registerWithOptions:options queue:queue handler: ^(NEHotspotHelperCommand * cmd) {
NEHotspotNetwork* network;
NSLog(@"cmd----%@", cmd);
NSLog(@"commandType:----%ld", (long)cmd.commandType);
NSLog(@"network---%@",cmd.network);
NSLog(@"networkList---%@",cmd.networkList);
//type为扫描wifi列表或评估
if (cmd.commandType == kNEHotspotHelperCommandTypeEvaluate || cmd.commandType ==kNEHotspotHelperCommandTypeFilterScanList) {
NSMutableArray *netArray = [NSMutableArray arrayWithCapacity:wifiArray.count];
for (network in cmd.networkList) {
for (SSIDInfo *wifiItem in wifiArray) {
if ([network.SSID isEqualToString:wifiItem.ssid]) {
//遍历查找网络 连接wife
[network setConfidence:kNEHotspotHelperConfidenceHigh];
[network setPassword:wifiItem.password];
[netArray addObject:network];
}
}
}
NEHotspotHelperResponse *response = [cmd createResponse:kNEHotspotHelperResultSuccess];
//设置网络
[response setNetworkList:netArray.copy];
//发送
[response deliver];
}
}];
NSLog(@"result :%d", returnType);
}

程序后台运行,进入系统WIFI设置页时,就会走NEHotspotHelperHandler回调,对代码中设置的网络,会进行密码填充和标记。

三、摸索中遇到的坑

1.待添加。。。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
- (void)settingSSID:(NSArray *)wifiArray
{
if (!IOS9) {
return ;
}
// 此处设置的内容会在WiFi列表中每个WiFi下边展示出来
NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:@"🔑WiFi一键连接",kNEHotspotHelperOptionDisplayName, nil];
//线程
dispatch_queue_t queue = dispatch_queue_create("com.testcompany.wifi", 0);
//注册HotspotHelper,returnType为YES才说明可用
BOOL returnType = [NEHotspotHelper registerWithOptions:options queue:queue handler: ^(NEHotspotHelperCommand * cmd) {
NEHotspotNetwork* network;
NSLog(@"cmd----%@", cmd);
NSLog(@"commandType:----%ld", (long)cmd.commandType);
NSLog(@"network---%@",cmd.network);
NSLog(@"networkList---%@",cmd.networkList);
//type为扫描wifi列表或评估
if (cmd.commandType == kNEHotspotHelperCommandTypeEvaluate || cmd.commandType ==kNEHotspotHelperCommandTypeFilterScanList) {
NSMutableArray *netArray = [NSMutableArray arrayWithCapacity:wifiArray.count];
for (network in cmd.networkList) {
for (SSIDInfo *wifiItem in wifiArray) {
if ([network.SSID isEqualToString:wifiItem.ssid]) {
//遍历查找网络 连接wife
[network setConfidence:kNEHotspotHelperConfidenceHigh];
[network setPassword:wifiItem.password];
[netArray addObject:network];
}
}
}
NEHotspotHelperResponse *response = [cmd createResponse:kNEHotspotHelperResultSuccess];
//设置网络
[response setNetworkList:netArray.copy];
//发送
[response deliver];
}
}];
NSLog(@"result :%d", returnType);
}

WIFI一键连接 iOS端 Configuration Profile 方式

Veröffentlicht am 2017-06-15

去年今日此门中,
人面桃花相映红.
人面不知何处去,
桃花依旧笑春风.

一、创建Configuration Profile

1.安装Apple Configurator工具

2.打开软件,工具栏:文件 - 新建描述文件

3.通用界面配置必备信息

(此处,配置文件的标识符相同,安装时,会覆盖安装)

4.左侧选择 Wi-Fi 项,进行 Wifi 信息配置

5.上述配置完成后,工具栏:文件 - 存储, 保存位置就会有一个 wifi.mobileconfig 文件

二、安装Configuration Profile

There are five ways to deploy configuration profiles:

1
2
3
4
5
1.Using Apple Configurator 2, available in the App Store
2.In an email message
3.On a webpage
4.Using over-the air configuration as described in Over-the-Air Profile Delivery and Configuration
5.Over the air using a Mobile Device Management Server

1
https://developer.apple.com/library/ios/featuredarticles/iPhoneConfigurationProfileRef/Introduction/Introduction.html

上述文档中,苹果提供了五种方式安装配置文件。

测试时,使用了 加载网页的形式,自己创建了一个配置文件,委托 后端同学 放入后台服务,得到配置文件的下载链接。

1
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"File_URL"]];

执行时,会调用系统safari加载下载链接,并自动转入系统设置,安装文件。安装完成,系统自动匹配wifi。
(测试:app里使用UIWevView控件加载下载链接,不会转入系统设置,无法完成安装)

iOS变更工程文件目录引起missing file警告

Veröffentlicht am 2017-05-15

斯人若彩虹,遇上方知有.

近期工作中做业务功能,创建类文件时,未指定文件目录,导致文件创建在根目录。显然很影响整个工程目录的结构,所以开始了文件的转移操作。

1
2
3
4
5
1.工程中,删除文件引用 Remove Reference
2.工程目录,类文件移动到指定目录中
3.工程中,拖动文件Copy items if needed

工程运行正常,但是出现了missing file警告,是由于Xcode自带的source control引起的

解决办法:

1
2
3
4
5
1.cd 到警告目录下
2.执行 git rm <文件名>
3.clean工程,重新运行

注意:

查资料,Preference - Source Control – 关闭Enable Source Control 可以解决此警告

经尝试,关闭Source Control可以解决此警告,但是工程文件目录下,原始目录文件又出现了,指定目录下也有一份文件。所以不建议使用此方法

位移枚举

Veröffentlicht am 2017-03-21

多少祸端起于觊觎别人的生活.

位移枚举

目录

  • 问题引入
  • 问题解析
  • 概念讲解
  • 问题解决办法(位移枚举)
  • 优化方法

问题引入

假定有一项考试,考试内容为辨别左、右两个方向,辨认正确得一分.写出考试和得分方法.

问题解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@interface Test : NSObject
@property (nonatomic, assign) NSInteger count;
@end
@implementation Test
// 辨认方向
- (void)recognizeLeft:(BOOL)isLeft
{
if (isLeft) {
_count += 1;
}
}
- (void)recognizeRight:(BOOL)isRight
{
if (isRight) {
_count += 1;
}
}
// 得分
- (NSInteger)testGrade
{
return _count;
}
@end

上述为最直接的方法,先调用辨认方向的方法,后查看成绩.

如果此时左、右代表两大块;左细分为左上,正左,左下;同理,右细分为右上,正右,右下.并且左上,左下, 右上,右下,辨认分值为2分.

那此时,recognizeLeft, recognizeRight各自变换成细分的三个方法,虽然能解决,但需要增加很多辨认方法,不是一个好的解决方式.

此时,把左(isLeft),右(isRight) 从BOOL值,转成枚举值,可解决上面问题.

1
2
3
4
5
6
7
8
9
10
11
12
13
typedef NS_ENUM (NSInteger,LeftType){
LeftTypeUnknown, // 不辨认左方向
LeftTypeTop, // 左上方
LeftTypeMiddle, // 正左方
LeftTypeBottom // 左下方
};
typedef NS_ENUM (NSInteger,RightType){
RightTypeUnknown, // 不辨认右方向
RightTypeTop, // 右上方
RightTypeMiddle, // 正右方
RightTypeBottom // 右下方
};

原来的recognizeLeft, recognizeRight修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 辨认方向
- (void)recognizeLeft:(LeftType)leftType
{
if (leftType == LeftTypeTop) {
_count += 2;
}else if (leftType == LeftTypeMiddle) {
_count += 1;
}else if (leftType == LeftTypeBottom) {
_count += 2;
}
}
- (void)recognizeRight:(RightType)rightType
{
if (rightType == RightTypeTop) {
_count += 2;
}else if (rightType == RightTypeMiddle) {
_count += 1;
}else if (rightType == RightTypeBottom) {
_count += 2;
}
}

这样,当辨认左上方时,若能辨认则传LeftTypeTop,不能则传LeftTypeUnknown或不调用该方法.其他各方向同理.这样存在的问题是,虽然方法数没增加,但是调用次数增多了.

下面,引入位移枚举的方法讲解.

概念讲解

位移枚举的定义:

1
2
3
4
5
6
typedef NS_OPTIONS (NSInteger,EnumType){
EnumTypeValue1 = 1 << 0, // 0b00000001
EnumTypeValue2 = 1 << 1, // 0b00000010
EnumTypeValue3 = 1 << 2, // 0b00000100
EnumTypeValue4 = 1 << 3 // 0b00001000
};

问题解决办法(位移枚举)

1
2
3
4
5
6
7
8
9
10
11
12
13
typedef NS_OPTIONS (NSInteger,LeftType){
LeftTypeUnknown = 1 << 0, // 不辨认左方向
LeftTypeTop = 1 << 1, // 左上方
LeftTypeMiddle = 1 << 2, // 正左方
LeftTypeBottom = 1 << 3 // 左下方
};
typedef NS_OPTIONS (NSInteger,RightType){
RightTypeUnknown = 1 << 0, // 不辨认右方向
RightTypeTop = 1 << 1, // 右上方
RightTypeMiddle = 1 << 2, // 正右方
RightTypeBottom = 1 << 3 // 右下方
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 辨认方向
- (void)recognizeLeft:(LeftType)leftType
{
if (leftType & LeftTypeTop) {
_count += 2;
}
if (leftType & LeftTypeMiddle) {
_count += 1;
}
if (leftType & LeftTypeBottom) {
_count += 2;
}
}
- (void)recognizeRight:(RightType)rightType
{
if (rightType & RightTypeTop) {
_count += 2;
}
if (rightType & RightTypeMiddle) {
_count += 1;
}
if (rightType & RightTypeBottom) {
_count += 2;
}
}

这样,我们调用的时候,就可以先赋值好枚举变量,调用辨认方法就可以了.

1
2
3
4
5
6
7
8
9
// 某人,左上,正左,左下,右上,右下都能辨认
- (void)test
{
LeftType leftType = LeftTypeTop | LeftTypeMiddle | LeftTypeBottom;
[self recognizeLeft:leftType];
RightType rightType = RightTypeTop | RightTypeBottom;
[self recognizeRight:rightType];
}

还是需要调用左,右两个方法,有了位移枚举,可以合并成一个方法.

优化方法

左、右枚举,合并

1
2
3
4
5
6
7
8
9
typedef NS_OPTIONS (NSInteger,OrientationType){
OrientationTypeUnknown = 1 << 0, // 不辨认方向
OrientationTypeLeftTop = 1 << 1, // 左上方
OrientationTypeLeftMiddle = 1 << 2, // 正左方
OrientationTypeLeftBottom = 1 << 3, // 左下方
OrientationTypeRightTop = 1 << 4, // 右上方
OrientationTypeRightMiddle = 1 << 5, // 正右方
OrientationTypeRightBottom = 1 << 6 // 右下方
};

辨认方法合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
- (void)recognizeOrientation:(OrientationType)orientationType
{
if (orientationType & OrientationTypeLeftTop) {
_count += 2;
}
if (orientationType & OrientationTypeLeftMiddle) {
_count += 1;
}
if (orientationType & OrientationTypeLeftBottom) {
_count += 2;
}
if (orientationType & OrientationTypeRightTop) {
_count += 2;
}
if (orientationType & OrientationTypeRightMiddle) {
_count += 1;
}
if (orientationType & OrientationTypeRightBottom) {
_count += 2;
}
if (orientationType & OrientationTypeUnknown) {
}
}

调用方法:

1
2
3
4
5
6
7
// 某人,左上,正左,左下,右上,右下都能辨认
- (void)test
{
OrientationType orientationType = OrientationTypeLeftTop | OrientationTypeLeftMiddle | OrientationTypeLeftBottom | OrientationTypeRightTop | OrientationTypeRightBottom;
[self recognizeOrientation:orientationType];
}

Mowangchen

我是莫忘尘,一个有着用代码改变世界梦想的人,这里是莫忘尘的收纳盒

5 Artikel
4 Tags
© 2018 Mowangchen
Erstellt mit Hexo
|
Theme — NexT.Muse v5.1.2