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
- #import <Foundation/Foundation.h>
- @interface dog : NSObject
- @property (nonatomic, assign) int age;
- @property (nonatomic, copy) void (^myBlock)();
- @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
- #import "dog.h"
- @implementation dog
- - (instancetype)init {
- if (self = [super init]) {
- self.age = 10;
- self.myBlock = ^{
- NSLog(@"%d",mySelf.age);
- };
- }
- return self;
- }
- - (void)dealloc {
- NSLog(@"dog - dealloc");
-
- Block_release(self.myBlock);
- [super dealloc];
- }
- @end
3.main.m文件
- int main(int argc, const charchar * argv[]) {
-
- blockARC_MRC();
-
- copyBlock();
- return 0;
- }
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
对象
- void blockARC_MRC(){
- __block dog *d = [[dog alloc] init];
- d.age = 12;
- NSLog(@"block引用前:d retainCount = %zd",d.retainCount);
- void (^myBlock)() = ^() {
- NSLog(@"d.age = %d",d.age);
- };
- NSLog(@"block引用后:d retainCount = %zd",d.retainCount);
-
- Block_copy(myBlock);
- NSLog(@"block copy后:d retainCount = %zd",d.retainCount);
- Block_release(myBlock);
- NSLog(@"block release后:d retainCount = %zd",d.retainCount);
- myBlock();
- NSLog(@"block调用后:d retainCount = %zd",d.retainCount);
-
- [d release];
- }
3.2 block中引用成员变量状况blog
// 1.没有调用d.age时,不须要__block
// 2.调用d.age时.必需要__block
ip
- void copyBlock() {
- __block dog *d = [[dog alloc] init];
- d.age = 12;
- NSLog(@"block引用前:d retainCount = %zd",d.retainCount);
- d.myBlock = ^{
- NSLog(@"myBlock -- %d",d.age);
- };
- NSLog(@"block引用后:d retainCount = %zd",d.retainCount);
- d.myBlock();
- NSLog(@"block调用后:d retainCount = %zd",d.retainCount);
-
- [d release];
- }
-- end