美文网首页
Block使用的一些注意事项&&不常见的使用方法

Block使用的一些注意事项&&不常见的使用方法

作者: fenglin | 来源:发表于2016-09-02 15:34 被阅读313次
  1. Block 也是一种 Objective-C 对象,可以用于赋值,当做参数传递,当做返回值,也可以放入 NSArray 和 NSDictionary 中。

1>. 如果是局部变量,Block是值传递

int a = 3;
void (^closure)() = ^{
      NSLog(@"a = %d",a);
};
a = 5;
closure();  //  a = 3;

2>. 如果是静态变量,全局变量,__block修饰的变量, Block是指针传递

static int a = 3;
void (^closure)() = ^{
      NSLog(@"a = %d",a);
};
a = 5;
closure();  //  a = 5;

3.1> . 解决循环引用

   @property (nonatomic , strong) void (^ failureBlock)();
   
   __weak typeof(self) weakSelf = self;

   _failureBlock = ^(){
  
     __strong typeof(weakSelf) strongSelf = weakSelf;
    
     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"%@",strongSelf);
      });
    };

    _failureBlock();

解释:1. _failureBlock 会对外面所有的‘强指针对象’进行强引用,包括 ‘self’ 对象 , 所以要在 外面用 __weak 声明一个弱指针类型的 self 供代码块里面使用。 2. 代码块中为什么要用 “__strong” 在抢引用 一次 “weakSelf” ,是为了防止在执行 “dispatch_after” 时 weakSelf 变成 nil.

3.2>

   __weak __typeof__(self) weakSelf = self;
  NSBlockOperation *op = [[NSBlockOperation alloc] init] ;
  [ op addExecutionBlock:^ { 
        __strong __typeof__(self) strongSelf = weakSelf;
       [strongSelf doSomething]; 
       [strongSelf doMoreThing];} 
  ];
 [someOperationQueue addOperation:op];

__strong这一句在执行的时候,如果 WeakSelf 还没有变成 nil,那么就会 retain self,让 self 在 block 执行期间不会变为 nil。
这样上面的 doSomething和 doMoreThing 要么全执行成功,要么全失败,不会出现一个成功一个失败,即执行到中间 self变成 nil 的情况。 如果想全部执行成功,可以用block 在引用一次。

总结 :Block 会对里面所有的外部的所有 ’强指针’ 进行全部‘强引用’。


blcok作为返回值的使用情况

参考下masonry框架的demo;

[blueView mas_makeConstraints:^(MASConstraintMaker *make) { 
   make.width.and.height.equalTo(redView);//使宽高等于  redView 
}];

make.width.and.height.equalTo(redView);

“equalTo” 的返回值就是 “Block”,然后在调用block,传入参数redView. 想必这种链式语法大家都很喜欢。下面是一个简单的小例子。
Calculate.h

@interface Calculate : NSObject
@property (nonatomic, readonly) double result;
-(Calculate * (^)(double number))plus;
@end

Calculate.m

@interface Calculate ()
@property (nonatomic, readwrite) double result;
@end
@implementation Calculate
- (Calculate * (^)(double number))plus{
return ^(double num){
_result += num;
return self;
};
}
@end

调用的时候:

Calculate *cal = [Calculate new];

double res = cal.plus(1).plus(2).plus(3).result;

NSLog(@"%f",res);  // 6.000000

可以一直用点语法一直plus,最后可以直接调用result得到我们的计算结果。

最后看一下怎么快速调用block,学过前端的同事感觉是不是很熟悉。

   (^(UIColor * backgroundColor){
          self.view.backgroundColor = backgroundColor;
    })([UIColor redColor]);

那么上面 "3.2>"的要想全部成功就可以这么写。

   __weak __typeof__(self) weakSelf = self;
NSBlockOperation *op = [[NSBlockOperation alloc] init] ;
[ op addExecutionBlock:^ {
    __strong __typeof__(self) strongSelf = weakSelf;
    
    (^{
        [strongSelf doSomething];
        [strongSelf doMoreThing];
    })();
    
}];
[someOperationQueue addOperation:op];

这样就会自动强引用“ strongSelf”。

相关文章

网友评论

      本文标题:Block使用的一些注意事项&&不常见的使用方法

      本文链接:https://www.haomeiwen.com/subject/yzohettx.html