IOS_Block_注意事项
2017-02-16 本文已影响16人
大美象
1、在使用block前需要对block指针做判空处理
- (NSURLSessionDataTask *)HEAD:(NSString *)URLString
parameters:(id)parameters
success:(void (^)(NSURLSessionDataTask *task))success
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
{
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"HEAD" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:^(NSURLSessionDataTask *task, __unused id responseObject) {
if (success) {
success(task);
}
} failure:failure];
[dataTask resume];
return dataTask;
}
2.避免循环引用
- block会飞内部的所有对象引用计数加1,会存在潜在的retain cycle,不过可以通过weak self的手段解决:使用方将self或成员变量加入block之前要先将self变为__weak
__weak __typeof(self)weakSelf = self;
在多线程环境下(block中的weakSelf有可能被析构的情况下),需要先将self转为strong指针,避免在运行到某个关键步骤时self对象被析构,如:
__weak __typeof(self)weakSelf = self;
AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
strongSelf.networkReachabilityStatus = status;
if (strongSelf.networkReachabilityStatusBlock) {
strongSelf.networkReachabilityStatusBlock(status);
}
};
- 更安全的用法,采用宏定义
#define weakify(var) __weak typeof(var) AHKWeak_##var = var;
#define strongify(var) \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wshadow\"") \
__strong typeof(var) var = AHKWeak_##var; \
_Pragma("clang diagnostic pop")
看下我们对这个宏的使用:
Model *model = [Model new];
weakify(self);
model.dataChanged = ^(NSString *title) {
strongify(self);
self.label.text = tile;
};
self.model = model;
3,在Block声明范围之内,所有变量都可以为其捕获
比如一下这段代码所定义的block,就引用了块以外的变量
int additionnal = 5;
int (^addBlock) (int a, int b) = ^(int a, int b){
return a+b+additionnal;
};
additionnal = addBlock(2,5);
4,默认情况下
,被block捕获的变量是不可以修改的
比如上面一段代码稍加改动
Paste_Image.png不过这个时候,在声明变量的时候可以加上__block修饰符,这样就可以在块内修改了
__block int additionnal = 5;
int (^addBlock) (int a, int b) = ^(int a, int b){
additionnal ++;
return a+b+additionnal;
};
additionnal = addBlock(2,5);
5,与4对应,定义在实例方法中的block,总能修改实例变量,因此声明时无需加__block
@interface EOCCLass ()
@property (nonatomic, strong) NSMutableArray *array;
@end
@implementation EOCCLass
- (void) doSomeThing{
void (^myBlock) () = ^{
_array = [[NSMutableArray alloc] initWithArray:@[@"1",@"2"]];
NSLog(@"_array = %@",_array);
};
}
`注意此段代码会引入循环引用,解决办法见条2`
@end
refrence from
@weakify_and%20@strongify_macros