您的位置:首页 > 移动开发 > IOS开发

iOS Block总结

2015-10-18 21:00 525 查看
1. 作为属性而存在的Block

testBlock.m文件里

@property (copy, nonatomic) void (^aBlock)(); // MRC下,block属性必须是显式标注copy策略; ARC下,其实可以不显式标明copy, xcode会自动对block属性采取copy策略

- (void)viewDidLoad {

[super viewDidLoad];

self.aBlock = ^{

    NSLog(@"%@",self);

  };

}

当block在栈内存时,Block对内部的对象只是弱引用


  1.1 copy关键字

    block默认是在存储在栈内存, 经过copy,会将block复制到堆内存

2. 在方法内部的Block

- (void)viewDidLoad {

[super viewDidLoad];

void (^innerFunctionBlock)() = ^{

NSLog(@"方法内部的block, 有人管这叫内联Block");

};

innerFunctionBlock();

}

3. 其他

- (void)viewDidLoad { ...2.里的代码块... }

void (^block)() = ^{

  NSLog(@"类似全局变量的Block, 其实和方法差不多");

};

总结: 1. 如果没有对block做copy操作, block就存储于栈内存

2. 如果对block做copy操作, block就存储于堆内存

3. 如果block存储于栈空间, 对block内部的所用到的外部对象,是弱引用

4. 如果block存储于堆空间, 对block内部的所用到的外部对象,是强引用

5. 解除循环引用的方法: 5.1 ARC:使用 __weak, 有时不能用__weak,那就用 __unsafe_unretained , 这种情况极少发生

              5.2 MRC:使用__block

5.3 在调用完block之后,将block = nil

6. NSInteger a = 1;

     void (^testBlock)(void) = ^{

      NSLog(@"a=%d",a);

     };

     ++a;

     testBlock();

打印出来肯定还是1, 因为block在编译阶段就确定了, 编译的时候block内部的 NSLog(@"a=%d",a) 等价于 NSLog(@"a=%d",1)

     想要block内部的a是引用,需要用到__block声明变量a: __block NSInteger a = 1; 这样编译编辑阶段,block内部的 NSLog(@"a=%d",a) 等价于 NSLog(@"a=%d",*(&a))

   7. 不要迷信xcode能帮你检查出所有block的循环引用问题,xcode只能检查出比较浅显的,这个尤其需要注意
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: