概述
- __strong:强引用,改变instance object RC,instance object指针默认为__strong
- __weak:弱引用,不改变instance object RC,当RC = 0 dealloc时,__weak instance object指针置nil
- __unsafe_unretained:顾名思义,unsafe和unretained,不改变instance object RC,当RC = 0,dealloc时,__unsafe_unretained instance object指针不置nil
注:__strong,__weak,__unsafe_unretained是ARC引入的关键字,因此其意义仅存于ARC下,在MRC下,__strong和____unsafe_unretained ignored,而__weak禁用
应用
@interface FBAnimal : NSObject
@end
@implementation FBAnimal
- (void)dealloc
{
NSLog(@"FBAnimal dealloc");
}
@end
@interface FBDog : FBAnimal
@end
@implementation FBDog
- (void)dealloc
{
NSLog(@"FBDog dealloc");
}
@end
- (void)instance_obj_ref
{
{
NSLog(@"-----RC change-----");
__strong FBAnimal *animal = [[FBDog alloc] init];
animal = [[FBDog alloc] init];
animal = nil;
animal = [[FBDog alloc] init];
}
{
NSLog(@"-----strong-----");
__strong FBAnimal *animal1 = [[FBDog alloc] init];
__strong FBAnimal *animal2 = animal1;
NSLog(@"animal1 = %p, animal2 = %p", animal1, animal2);
animal1 = nil;
NSLog(@"animal1 = %p, animal2 = %p", animal1, animal2);
}
{
NSLog(@"-----weak-----");
__strong FBAnimal *animal1 = [[FBDog alloc] init];
__weak FBAnimal *animal2 = animal1;
NSLog(@"animal1 = %p, animal2 = %p", animal1, animal2);
animal1 = nil;
NSLog(@"animal1 = %p, animal2 = %p", animal1, animal2);
}
{
NSLog(@"-----unsafe_unretained-----");
__strong FBAnimal *animal1 = [[FBDog alloc] init];
__unsafe_unretained FBAnimal *animal2 = animal1;
NSLog(@"animal1 = %p, animal2 = %p", animal1, animal2);
animal1 = nil;
NSLog(@"animal1 = %p, animal2 = %p", animal1, animal2);
}
}
output:
-----RC change-----
FBDog dealloc
FBAnimal dealloc
FBDog dealloc
FBAnimal dealloc
FBDog dealloc
FBAnimal dealloc
-----strong-----
animal1 = 0x7faa835a4b50, animal2 = 0x7faa835a4b50
animal1 = 0x0, animal2 = 0x7faa835a4b50
FBDog dealloc
FBAnimal dealloc
-----weak-----
animal1 = 0x7faa835a4b50, animal2 = 0x7faa835a4b50
FBDog dealloc
FBAnimal dealloc
animal1 = 0x0, animal2 = 0x0
-----unsafe_unretained-----
animal1 = 0x7faa835a6500, animal2 = 0x7faa835a6500
FBDog dealloc
FBAnimal dealloc
animal1 = 0x0, animal2 = 0x7faa835a6500
总结:
- __strong指向instance object,RC加1,__strong不再指向instance object,RC减1
- __strong不再指向instance object包括__strong指向另一instance object,__strong置nil,__strong离开作用域
- __weak不改变RC值,当RC = 0 dealloc时,__weak置nil
- __unsafe_unretained,即unsafe+unretained,不改变RC值,当RC = 0 dealloc时,__unsafe_unretained不置nil
strong&weak&unsafe_unretained
strong,weak,unsafe_unretained修饰property,本质修饰property合成的对应数据成员(如果有合成数据成员),分别对应__strong,__weak,__unsafe_unretained,因此strong,weak,unsafe_unretained只能修饰类类型property,显然在ARC下使用才有意义
@interface FBAnimal : NSObject
@end
@implementation FBAnimal
- (void)dealloc
{
NSLog(@"FBAnimal dealloc");
}
@end
@interface FBDog : FBAnimal
@end
@implementation FBDog
- (void)dealloc
{
NSLog(@"FBDog dealloc");
}
@end
@interface FBFarm : NSObject
//@property(strong) NSUInteger area;
@property(strong) FBAnimal* strongAnimal;
@property(weak) FBAnimal* weakAnimal;
@property(unsafe_unretained) FBAnimal* unsafe_unretainedAnimal;
@end
@implementation FBFarm
@end
- (void)property_objc_ref
{
{
NSLog(@"-----RC change-----");
FBFarm *farm = [[FBFarm alloc] init];
farm.strongAnimal = [[FBDog alloc] init];
farm.strongAnimal = [[FBDog alloc] init];
farm.strongAnimal = nil;
farm.strongAnimal = [[FBDog alloc] init];
}
{
NSLog(@"-----strong-----");
FBFarm *farm1 = [[FBFarm alloc] init];
FBFarm *farm2 = [[FBFarm alloc] init];
farm1.strongAnimal = [[FBDog alloc] init];
farm2.strongAnimal = farm1.strongAnimal;
NSLog(@"farm1.strongAnimal = %p, farm2.strongAnimal = %p", farm1.strongAnimal, farm2.strongAnimal);
farm1.strongAnimal = nil;
NSLog(@"farm1.strongAnimal = %p, farm2.strongAnimal = %p", farm1.strongAnimal, farm2.strongAnimal);
}
{
NSLog(@"-----weak-----");
NSLog(@"-----strong-----");
FBFarm *farm1 = [[FBFarm alloc] init];
FBFarm *farm2 = [[FBFarm alloc] init];
farm1.strongAnimal = [[FBDog alloc] init];
farm2.weakAnimal = farm1.strongAnimal;
NSLog(@"farm1.strongAnimal = %p, farm2.weakAnimal = %p", farm1.strongAnimal, farm2.weakAnimal);
farm1.strongAnimal = nil;
NSLog(@"farm1.strongAnimal = %p, farm2.strongAnimal = %p", farm1.strongAnimal, farm2.strongAnimal);
}
{
NSLog(@"-----unsafe_unretained-----");
NSLog(@"-----strong-----");
FBFarm *farm1 = [[FBFarm alloc] init];
FBFarm *farm2 = [[FBFarm alloc] init];
farm1.strongAnimal = [[FBDog alloc] init];
farm2.unsafe_unretainedAnimal = farm1.strongAnimal;
NSLog(@"farm1.strongAnimal = %p, farm2.unsafe_unretainedAnimal = %p", farm1.strongAnimal, farm2.unsafe_unretainedAnimal);
farm1.strongAnimal = nil;
NSLog(@"farm1.strongAnimal = %p, farm2.unsafe_unretainedAnimal = %p", farm1.strongAnimal, farm2.unsafe_unretainedAnimal);
}
}
output:
-----RC change-----
FBDog dealloc
FBAnimal dealloc
FBDog dealloc
FBAnimal dealloc
FBDog dealloc
FBAnimal dealloc
-----strong-----
farm1.strongAnimal = 0x7fd8b3f1b3a0, farm2.strongAnimal = 0x7fd8b3f1b3a0
farm1.strongAnimal = 0x0, farm2.strongAnimal = 0x7fd8b3f1b3a0
FBDog dealloc
FBAnimal dealloc
-----weak-----
-----strong-----
farm1.strongAnimal = 0x7fd8b3f0ba20, farm2.weakAnimal = 0x7fd8b3f0ba20
FBDog dealloc
FBAnimal dealloc
farm1.strongAnimal = 0x0, farm2.strongAnimal = 0x0
-----unsafe_unretained-----
-----strong-----
farm1.strongAnimal = 0x7fd8b3f15d00, farm2.unsafe_unretainedAnimal = 0x7fd8b3f15d00
FBDog dealloc
FBAnimal dealloc
farm1.strongAnimal = 0x0, farm2.unsafe_unretainedAnimal = 0x7fd8b3f15d00
(lldb)
总结:
- strong,weak,unsafe_unretained修饰类类型property本质修饰property合成的对应数据成员(如果有合成数据成员),分别对应__strong,__weak,__unsafe_unretained
- 如果unsafe_unretained property指向的instance object已经dealloc,则访问该unsafe_unretained property会crash