block 的ARC和MRC中的区别

block在ARC和MRC中的声明引用有些区别.xcode

     /**
     block能够存储在栈中,也能够在堆中
     默认存储在栈中,不须要管理内存
     存储在堆中的block会对block进行retain操做
     */
    //(MRC)block在堆中时,不想对block进行retain操做,前面加__block
    //(ARC)前面加__weak或__unsafe_unretained
    //__weak和__unsafe_unretained的区别:__weak则在释放时会对对象赋值nil,后者不会ide

    //Block_copy使栈中的block转移到堆中,并对block会引用的对象进行retain操做
    //避免block引用的对象进行retain操做,在引用对象声明时前面加__blockatom

1.dog.h (NSObject类)spa

//block用copy来定义,这样block存在于堆中
//若是block不是copy到堆中,引用完了对象还在,但block被释放了
.net

[objc]  view plain  copy
 print ?
  1. #import <Foundation/Foundation.h>  
  2. @interface dog : NSObject  
  3. @property (nonatomic, assign) int age;  
  4. @property (nonatomiccopyvoid (^myBlock)();  
  5. @end  

2.dog.m

//引用self.age会使retainCount = 2的
//所以以__block typeof(self) mySelf = self;方式从新定义selfcode

2.1 在block nslog中不调用d.age状况下,不须要从新定义selform

2.2 在block nslog中调用d.age状况下,须要从新定义self

[objc]  view plain  copy
 print ?
  1. #import "dog.h"  
  2. @implementation dog  
  3. - (instancetype)init {    
  4.     if (self = [super init]) {  
  5.         self.age = 10;  
  6.         self.myBlock = ^{  
  7.             NSLog(@"%d",mySelf.age);  
  8.         };  
  9.     }  
  10.     return self;  
  11. }  
  12. - (void)dealloc {  
  13.        NSLog(@"dog - dealloc");  
  14. //对定义时copy的block进行释放  
  15.        Block_release(self.myBlock);  
  16.        [super dealloc];  
  17. }  
  18. @end  
3.main.m文件

[objc]  view plain  copy
 print ?
  1. int main(int argc, const charchar * argv[]) {  
  2. //3.1 block在ARC和MRC中的状况  
  3.     blockARC_MRC();  
  4. //3.2 copy block状况  
  5.     copyBlock();     
  6.     return 0;  
  7. }  
3.1 block在ARC和MRC中的状况

     /**
     block能够存储在栈中,也能够在堆中
     默认存储在栈中,不须要管理内存
     存储在堆中的block会对block进行retain操做
     */
    //(MRC)block在堆中时,不想对block进行retain操做,前面加__block
    //(ARC)前面加__weak或__unsafe_unretained
    //__weak和__unsafe_unretained的区别:__weak则在释放时会对对象赋值nil,后者不会
    
    //Block_copy使栈中的block转移到堆中,并对block会引用的对象进行retain操做
    //避免block引用的对象进行retain操做,在引用对象声明时前面加__block
对象

[objc]  view plain  copy
 print ?
  1. void blockARC_MRC(){  
  2.     __block dog *d = [[dog alloc] init];  
  3.     d.age = 12;  
  4.     NSLog(@"block引用前:d retainCount = %zd",d.retainCount);  
  5.     void (^myBlock)() = ^() {  
  6.         NSLog(@"d.age = %d",d.age);  
  7.     };  
  8.     NSLog(@"block引用后:d retainCount = %zd",d.retainCount);  
  9.       
  10.     Block_copy(myBlock);  
  11.     NSLog(@"block copy后:d retainCount = %zd",d.retainCount);  
  12.     Block_release(myBlock);  
  13.     NSLog(@"block release后:d retainCount = %zd",d.retainCount);  
  14.     myBlock();  
  15.     NSLog(@"block调用后:d retainCount = %zd",d.retainCount);  
  16.       
  17.     [d release];  
  18. }  

3.2 block中引用成员变量状况blog

//   1.没有调用d.age时,不须要__block
//   2.调用d.age时.必需要__block
ip

[objc]  view plain  copy
 print ?
  1. void copyBlock() {  
  2.     __block dog *d = [[dog alloc] init];  
  3.     d.age = 12;  
  4.     NSLog(@"block引用前:d retainCount = %zd",d.retainCount);  
  5.     d.myBlock = ^{  
  6.         NSLog(@"myBlock -- %d",d.age);  
  7.     };  
  8.     NSLog(@"block引用后:d retainCount = %zd",d.retainCount);  
  9.     d.myBlock();  
  10.     NSLog(@"block调用后:d retainCount = %zd",d.retainCount);  
  11.       
  12.     [d release];  
  13. }  

-- end