二、 _weak修饰词
因为使用_strong修饰词,易出现循环引用,使用_weak来解决。
(1)循环引用的例子--在类中成员变量可能出现的循环引用
@interface Test : NSObject {
id _strong obj;
}
(void)setObject:(id __strong)obj;
@end
@implementation Test
- (id)init
{
self = [super init];
return self;
}
(void)setObject:(id __strong)obj {
obj_ = obj;
}
@end
下面这段代码将产生循环引用
{
id test0 = [[Test alloc] init];//test0对对象A有强引用,[[Test alloc] init]为对象A
id test1 = [[Test alloc] init];//test1对对象B有强引用,[[Test alloc] init]为对象B
[test0 setObject:test1]; //对象A的成员变量obj_对对象B有强引用,此时对象A的的成员变量以及test1对对象B有有强引用。
[test1 setObject:test0]; // 对象B的成员变量obj_及test0对对象A有强引用。
}
控制流出了这段代码区域时,变量test0对A的强引用消失,对象A被自动释放。类似的对象B也被自动释放。但是对象A的成员变量obj_ 还强引用对象B,从而内存泄漏
解决方法
@interface Test : NSObject {
id _weak obj;
}
-(void)setObject:(id __strong)obj;
@end
(2)self reference造成的循环引用
什么是’self reference’
对象对自己的引用简称’self reference’
例子
id test = [[Test alloc] init];
[test setObject:test];
避免’self reference’--使用_weak属性修饰词
_weak修饰词提供一个弱引用,使用_weak可以避免循环引用。
id _weak obj = [[NSObject alloc] init];
上面代码编译后会出现警告:warning: assigning retained obj to weak variable; obj will be released after assignment [-Warc-unsafe-retained-assign]
{
id __strong obj0 = [[NSObject alloc] init]; //变量obj0被_strong修饰,拥有[[NSObject alloc] init]的对象所有权
id __weak obj1 = obj0; //obj1对[[NSObject alloc] init]有一个弱引用
}
//离开此区域,对象的强引用消失,对象被自动释放。因为弱引用对对象没有拥有权。
当一个被weak修饰的变量对一个对象有一个引用,并且这个对象消失时,这个弱引用也就自动消失。这意味着变量被分配为nil。
id __weak obj1 = nil; {
id __strong obj0 = [[NSObject alloc] init];
obj1 = obj0;
NSLog(@”A: %@”, obj1); }
NSLog(@”B: %@”, obj1);
The result is:
A:
B: (null)
(3)什么是内存泄漏
内存泄漏指一些被认为释放的对象仍保留在内存中,循环引用常造成内存泄漏