一、Block
1、使用copy
因为block属于代码块,存放在栈区,释放是由编译器决定的,如果不对block进行copy操作,之后使用的时候很可能block已经释放。所以出于安全考虑,需要先将block copy到堆区。在ARC模式中,系统自动对block进行copy操作,但是MRC需要手动进行 copy。(在ARC中用strong修饰block也是可以的,系统会自动进行copy)
2、循环引用:
因为block在拷贝到堆上的时候,会retain其引用的外部变量,那么如果block中如果引用了他的宿主对象,那很有可能引起循环引用
所以为了防止循环引用引起的内存泄漏,使用__weak。(循环引用也就是对象之间互相持有,或者形成一个retail cycle)
注:
只要 block中用到了对象的属性或者函数,(self.string
,_string
, [self ChangeString]
)block就会持有该对象而不是该对象中的某个属性或者函数。(解释:即对于block中调用self.string,持有的是self而不是string)
例如:
① 对self弱引用
// @property (nonatomic, copy) NSString *blockString;
__weak typeof(self) weakSelf = self;
self.myBlock = ^() {
NSString *localString = weakSelf.blockString;
};
② 对属性弱引用
// NSString *_blockString; 在block中修改需要加修饰词__block
__block __weak typeof(_blockString) weakBlockStr = _blockString;
self.myBlock = ^() {
weakBlockStr = @“weakBlockStr”;
};
3、参考资料:
iOS内存管理(4)--Block属性用copy修饰 & 避免循环引用的问题
小结iOS中的copy
二、Delegate
1、使用weak/assign
使用弱引用是为了防止循环引用
ARC中使用weak,释放之后会自动置空;
MRC中使用assign,但是需要手动置空,即delegate = nil;
如果使用强引用:
viewcontroller-->tableview-->tableview.Delegate-->viewcontroller 这样会造成循环引用。
网友评论