__block 与 __weak的区别理解

原创 2016年06月01日 22:00:24

__block 与 __weak的区别理解

Blocks理解:

Blocks可以访问局部变量,但是不能修改。

  • __block对象在block中是可以被修改、重新赋值的。
  • __block对象在block中不会被block强引用一次,从而不会出现循环引用问题。

使用了__weak修饰符的对象,作用等同于定义为weak的property。自然不会导致循环引用问题,因为苹果文档已经说的很清楚,当原对象没有任何强引用的时候,弱引用指针也会被设置为nil。

因此,__block和__weak修饰符的区别其实是挺明显的:
1.__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。
2.__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。
3.__block对象可以在block中被重新赋值,__weak不可以。
PS:__unsafe_unretained修饰符可以被视为iOS SDK 4.3以前版本的__weak的替代品,不过不会被自动置空为nil。所以尽可能不要使用这个修饰符。

  1. 如果修改局部变量,需要加__block
 __block int multiplier = 7;
     int (^myBlock)(int) = ^(int num) {
         multiplier ++;//这样就可以了
         return num * multiplier;
     };
  1. 如果局部变量是数组或者指针的时候只复制这个指针,两个指针指向同一个地址,block只修改指针上的内容。如:
NSMutableArray *mArray = [NSMutableArray arrayWithObjects:@"a",@"b",@"abc",nil];
    NSMutableArray *mArrayCount = [NSMutableArray arrayWithCapacity:1];
    [mArray enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock: ^(id obj,NSUInteger idx, BOOL *stop){
        [mArrayCount addObject:[NSNumber numberWithInt:[obj length]]];
    }];

    NSLog(@"%@",mArrayCount);

**例子里面确实没有修改mArrayCount这个局部变量啊。mArrayCount是一个指针,指向一个可变长度的数组。在block里面,并没有修改这个指针,而是修改了这个指针指向的数组。换句话说,mArrayCount是一个整数,保存的是一块内存区域的地址,在block里,并没有改变这个地址,而是读取出这个地址,然后去操作这块地址空间的内容。

这是允许的,因为声明block的时候实际上是把当时的临时变量又复制了一份,在block里即使修改了这些复制的变量,也不影响外面的原始变量。即所谓的闭包。

但是当变量是一个指针的时候,block里只是复制了一份这个指针,两个指针指向同一个地址。所以,在block里面对指针指向内容做的修改,在block外面也一样生效。
**

__weak __typeof(&*self)weakSelf =self; 等同于

__weak UIViewController *weakSelf =self;

为什么不用__block 是因为通过引用来访问self的实例变量 ,self被retain,block也是一个强引用,引起循环引用,用__week是弱引用,当self释放时,weakSelf已经等于nil。

**扩展:NSTimer注意避免循环引用的地方,需要找个合适的时机和地方来 invalidate timer
**

在引用计数的环境里面,默认情况下当你在block里面引用一个Objective-C对象的时候,该对象会被retain。当你简单的引用了一个对象的实例变量时,它同样被retain。但是被__block存储类型修饰符标记的对象变量不会被retain

注意:在垃圾回收机制里面,如果你同时使用__weak和__block来标识一个变量,那么该block将不会保证它是一直是有效的。 如果你在实现方法的时候使用了block,对象的内存管理规则更微妙:也是(__weak与__block区别:)

1、如果你通过引用来访问一个实例变量,self会被retain。
2、如果你通过值来访问一个实例变量,那么变量会被retain

版权声明:本文为博主原创文章,未经博主允许不得转载。

iOS开发之 __block 与 __weak的区别理解

资料来源1 资料来源2__block对象在block中是可以被修改、重新赋值的。使用了__weak修饰符的对象,作用等同于定义为weak的property。自然不会导致循环引用问题,因为苹果文档已经...
  • wtdask
  • wtdask
  • 2017年07月28日 10:32
  • 191

__block 与 __weak的区别理解 补充

Blocks理解: Blocks可以访问局部变量,但是不能修改 如果修改局部变量,需要加__block __block int multiplier = 7; int (^myB...

_block 与 __weak的区别理解

Blocks理解: Blocks可以访问局部变量,但是不能修改 如果修改局部变量,需要加__block __block int multiplier = 7; int (^myB...

__block 与 __weak的区别理解

声明block的时候实际上是把当时的临时变量又复制了一份,在block里即使修改了这些复制的变量,也不影响外面的原始变量。即所谓的闭包。但是当变量是一个指针的时候,block里只是复制了一份这个指针,...

__block 与 __weak的区别理解

Blocks理解: Blocks可以访问局部变量,但是不能修改 如果修改局部变量,需要加__block __block int multiplier = 7; int (^myBlock...

__block 与 __weak的区别理解

Blocks理解: Blocks可以访问局部变量,但是不能修改 如果修改局部变量,需要加__block __block int multiplier = 7; int...

__weak与__block区别,深层理解两者区别

准备工作 首先我定义了一个类 MyObject 继承 NSObject,并添加了一个属性 text,重写了description方法,返回 text 的值。这个主要是因为编译器本身对 NSStr...

__weak和__block探究与区别

准备工作 首先我定义了一个类 MyObject 继承 NSObject,并添加了一个属性 text,重写了description方法,返回 text 的值。这个主要是因为编译器本身对 N...

__block 与 __weak的区别与使用

1.__block对象在block中是可以被修改、重新赋值的。  2.__block对象在block中不会被block强引用一次,从而不会出现循环引用问题。 3.__block不管是ARC还是MRC模...

__weak与__block区别

__weak与__block区别公司最近在招 iOS,我面试了几个人,问到 block 避免循环引用的问题时,发现好多人都说通过添加 __block 修饰词来避免。再加上我对__block和__wea...
  • loumzy
  • loumzy
  • 2015年08月21日 14:44
  • 1210
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:__block 与 __weak的区别理解
举报原因:
原因补充:

(最多只允许输入30个字)