runtime

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.避免循环引用

__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

上一篇 下一篇

猜你喜欢

热点阅读