block 的ARC和MRC中的区别

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

1.dog.h (NSObject类)

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

#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;方式重新定义self

2.1 在block nslog中不调用d.age情况下,不需要重新定义self

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");
//对定义时copy的block进行释放
       Block_release(self.myBlock);
       [super dealloc];
}
@end
3.main.m文件

int main(int argc, const char * argv[]) {
//3.1 block在ARC和MRC中的情况
    blockARC_MRC();
//3.2 copy block情况
    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中引用成员变量情况

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

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

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值