天天看点

__Block和__Weak的区别

__Block

1.__block对象在block中是可以被修改、重新赋值的。

如果修改局部变量,需要加__block

__block int multiplier = ;
     int (^myBlock)(int) = ^(int num) {
         multiplier ++;//这样就可以了
         return num * multiplier;

     };
           

2.__block对象在block中不会被block强引用一次,从而不会出现循环引用问题。

3、如果局部变量是数组或者指针的时候只复制这个指针,两个指针指向同一个地址,block只修改指针上的内容

NSMutableArray *mArray = [NSMutableArray arrayWithObjects:@"a",@"b",@"abc",nil];
    NSMutableArray *mArrayCount = [NSMutableArray arrayWithCapacity:];
    [mArray enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock: ^(id obj,NSUInteger idx, BOOL *stop){
        [mArrayCount addObject:[NSNumber numberWithInt:[obj length]]];
    }];

    NSLog(@"%@",mArrayCount);
           

__Weak

__weak __typeof(&*self)weakSelf =self;

等同于
__weak UIViewController *weakSelf =self;
           

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

使用了__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。所以尽可能不要使用这个修饰符。

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

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

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