天天看點

oc——類——屬性——修飾詞——assign retain copy strong weak unsafe_unretained

MRC

@interface FBFood : NSObject<NSCopying>
{
    NSString *_name;
    NSString *_color;
}

@end

@implementation FBFood

- (id)copyWithZone:(NSZone *)zone
{
    NSLog(@"class %s copy", object_getClassName(self));
    
    FBFood *food = [[[self class] allocWithZone:zone] init];
    food->_name = [self->_name copy];
    food->_color = [self->_color copy];
    
    return food;
}

- (void)dealloc
{
    NSLog(@"dealloc FBFood");
    [super dealloc];
}

@end
           

assign

@interface FBAnimal : NSObject

@property (assign) FBFood *food;

@end

@implementation FBAnimal

@end
           
- (void)mrc_assign
{
    FBFood *srcFood = [[FBFood alloc] init];
    
    FBAnimal *animal = [[FBAnimal alloc] init];
    animal.food = srcFood;
    
    FBFood *destFood;
    
    NSLog(@"source: food = %p, RC = %ld", srcFood, [srcFood retainCount]);
    
    destFood = animal.food;
    
    NSLog(@"property: food = %p, RC = %ld", destFood, [destFood retainCount]);
    
    [srcFood release];
    
    NSLog(@"source: food = %p", srcFood);
    
    destFood = animal.food;
    
    NSLog(@"property: food = %p", destFood);
}
           

output:

source: food = 0x7f9de15c3550, RC = 1
property: food = 0x7f9de15c3550, RC = 1
dealloc FBFood
source: food = 0x7f9de15c3550
property: food = 0x7f9de15c3550
           

assign property food在implementation中合成以下Method定義

@implementation FBAnimal
{
    FBFood *_food
}

- (FBFood *)food
{
    return _food;
}

- (void)setFood:(FBFood *)food
{
    _food = food;
}

@end
           

注1:assign既可修飾非oc類property,也可修飾oc類property 注2:非oc類property應使用assign 注3:oc類property不應使用assign,否則導緻RC混亂

copy

@interface FBAnimal : NSObject

@property (copy) FBFood *food;

@end

@implementation FBAnimal

@end
           
- (void)mrc_copy
{
    FBFood *srcFood = [[FBFood alloc] init];
    
    FBAnimal *animal = [[FBAnimal alloc] init];
    animal.food = srcFood;
    
    NSLog(@"source: food = %p, RC = %ld", srcFood, [srcFood retainCount]);
    
    FBFood *destFood = animal.food;
    
    NSLog(@"property: food = %p, RC = %ld", destFood, [destFood retainCount]);
}
           

output:

class FBFood copy
source: food = 0x7f97b170d700, RC = 1
property: food = 0x7f97b17a7e20, RC = 2
           

copy property food在implementation中合成以下Method定義

@implementation FBAnimal
{
    FBFood *_food
}

- (FBFood *)food
{
    [_food retain];
    
    return _food;
}

- (void)setFood:(FBFood *)food
{
    [_food release];
    _food = [food copy];
}

@end
           

注:copy隻能修飾oc類property,且oc類必須遵守NSCopying

retain

@interface FBAnimal : NSObject

@property (retain) FBFood *food;

@end

@implementation FBAnimal

@end
           
- (void)mrc_retain
{
    FBFood *srcFood = [[FBFood alloc] init];
    
    FBAnimal *animal = [[FBAnimal alloc] init];
    animal.food = srcFood;
    
    NSLog(@"source: food = %p, RC = %ld", srcFood, [srcFood retainCount]);
    
    FBFood *destFood = animal.food;
    
    NSLog(@"property: food = %p, RC = %ld", destFood, [destFood retainCount]);
}
           

output:

source: food = 0x7fc0a2c09540, RC = 2
property: food = 0x7fc0a2c09540, RC = 3
           

retain property food在implementation中合成以下Method定義

@implementation FBAnimal
{
    FBFood *_food
}

- (FBFood *)food
{
    [_food retain];
    
    return _food;
}

- (void)setFood:(FBFood *)food
{
    [_food release];
    _food = [food retain];
}

@end
           

注:retain隻能修飾oc類property

strong

@interface FBAnimal : NSObject

@property (strong) FBFood *food;

@end

@implementation FBAnimal

@end
           
- (void)mrc_strong
{
    FBFood *srcFood = [[FBFood alloc] init];
    
    FBAnimal *animal = [[FBAnimal alloc] init];
    animal.food = srcFood;
    
    NSLog(@"source: food = %p, RC = %ld", srcFood, [srcFood retainCount]);
    
    FBFood *destFood = animal.food;
    
    NSLog(@"property: food = %p, RC = %ld", destFood, [destFood retainCount]);
}
           

output:

source: food = 0x7fee50717bf0, RC = 2
property: food = 0x7fee50717bf0, RC = 3
           

strong property food在implementation中合成以下Method定義

@implementation FBAnimal
{
    FBFood *_food
}

- (FBFood *)food
{
    [_food retain];
    
    return _food;
}

- (void)setFood:(FBFood *)food
{
    [_food release];
    _food = [food retain];
}

@end
           

注:MRC下strong同retain

weak

MRC下不支援weak修飾詞

unsafe_unretained

@interface FBAnimal : NSObject

@property (unsafe_unretained) FBFood *food;

@end

@implementation FBAnimal

@end
           
- (void)mrc_unsafe_unretained
{
    FBFood *srcFood = [[FBFood alloc] init];
    
    FBAnimal *animal = [[FBAnimal alloc] init];
    animal.food = srcFood;
    
    FBFood *destFood;
    
    NSLog(@"source: food = %p, RC = %ld", srcFood, [srcFood retainCount]);
    
    destFood = animal.food;
    
    NSLog(@"property: food = %p, RC = %ld", destFood, [destFood retainCount]);
    
    [srcFood release];
    
    NSLog(@"source: food = %p", srcFood);
    
    destFood = animal.food;
    
    NSLog(@"property: food = %p", destFood);
}
           

output:

source: food = 0x7f96d361d480, RC = 1
property: food = 0x7f96d361d480, RC = 1
dealloc FBFood
source: food = 0x7f96d361d480
property: food = 0x7f96d361d480
           

unsafe_unretained property food在implementation中合成以下Method定義

@implementation FBAnimal
{
    FBFood *_food
}

- (FBFood *)food
{
    return _food;
}

- (void)setFood:(FBFood *)food
{
    _food = food;
}

@end
           

注:MRC下unsafe_unretained同assign

ARC

@interface FBFood : NSObject<NSCopying>
{
    NSString *_name;
    NSString *_color;
}

@end

@implementation FBFood

- (id)copyWithZone:(NSZone *)zone
{
    NSLog(@"class %s copy", object_getClassName(self));
    
    FBFood *food = [[[self class] allocWithZone:zone] init];
    food->_name = [self->_name copy];
    food->_color = [self->_color copy];
    
    return food;
}

- (void)dealloc
{
    NSLog(@"dealloc FBFood");
}

@end
           

assign

@interface FBAnimal : NSObject

@property (assign) FBFood *food;

@end

@implementation FBAnimal

@end
           
- (void)arc_assign
{
    FBFood *food = [[FBFood alloc] init];
    
    FBAnimal *animal = [[FBAnimal alloc] init];
    animal.food = food;
    
    NSLog(@"source: food = %p", food);
    NSLog(@"property: food = %p", animal.food);
    
    food = nil;
    
    NSLog(@"source: food = %p", food);
    NSLog(@"property: food = %p", animal.food);
}
           

output:

source: food = 0x7fbb41da1bf0
property: food = 0x7fbb41da1bf0
dealloc FBFood
source: food = 0x0
(lldb)
           

assign property food在implementation中合成以下Method定義

@implementation FBAnimal
{
    __unsafe_unretained FBFood *_food
}

- (FBFood *)food
{
    return _food;
}

- (void)setFood:(FBFood *)food
{
    _food = food;
}

@end
           

注1:assign既可修飾非oc類property,也可修飾oc類property 注2:非oc類property應使用assign 注3:oc類property使用assign同unsafe_unretained

copy

@interface FBAnimal : NSObject

@property (copy) FBFood *food;

@end

@implementation FBAnimal

@end
           
- (void)arc_copy
{
    FBFood *food = [[FBFood alloc] init];
    
    FBAnimal *animal = [[FBAnimal alloc] init];
    animal.food = food;
    
    NSLog(@"source: food = %p", food);
    NSLog(@"property: food = %p", animal.food);
    
    food = nil;
    
    NSLog(@"source: food = %p", food);
    NSLog(@"property: food = %p", animal.food);
}
           

output:

class FBFood copy
source: food = 0x7fe2b061dfc0
property: food = 0x7fe2b061cf70
dealloc FBFood
source: food = 0x0
property: food = 0x7fe2b061cf70
dealloc FBFood
           

copy property food在implementation中合成以下Method定義

@implementation FBAnimal
{
    __strong FBFood *_food
}

- (FBFood *)food
{
    return _food;
}

- (void)setFood:(FBFood *)food
{
    _food = [food copy];
}

@end
           

注:copy隻能修飾oc類property,且oc類必須遵守NSCopying

strong

@interface FBAnimal : NSObject

@property (strong) FBFood *food;

@end

@implementation FBAnimal

@end
           
- (void)arc_strong
{
    FBFood *food = [[FBFood alloc] init];
    
    FBAnimal *animal = [[FBAnimal alloc] init];
    animal.food = food;
    
    NSLog(@"source: food = %p", food);
    NSLog(@"property: food = %p", animal.food);
    
    food = nil;
    
    NSLog(@"source: food = %p", food);
    NSLog(@"property: food = %p", animal.food);
}
           

output:

source: food = 0x7f8328f15000
property: food = 0x7f8328f15000
source: food = 0x0
property: food = 0x7f8328f15000
dealloc FBFood
           

strong property food在implementation中合成以下Method定義

@implementation FBAnimal
{
    __strong FBFood *_food
}

- (FBFood *)food
{
    return _food;
}

- (void)setFood:(FBFood *)food
{
    _food = food;
}

@end
           

注:strong隻能修飾oc類property

weak

@interface FBAnimal : NSObject

@property (weak) FBFood *food;

@end

@implementation FBAnimal

@end
           
- (void)arc_weak
{
    FBFood *food = [[FBFood alloc] init];
    
    FBAnimal *animal = [[FBAnimal alloc] init];
    animal.food = food;
    
    NSLog(@"source: food = %p", food);
    NSLog(@"property: food = %p", animal.food);
    
    food = nil;
    
    NSLog(@"source: food = %p", food);
    NSLog(@"property: food = %p", animal.food);
}
           

output:

source: food = 0x7f807aea34b0
property: food = 0x7f807aea34b0
dealloc FBFood
source: food = 0x0
property: food = 0x0
           

weak property food在implementation中合成以下Method定義

@implementation FBAnimal
{
    __weak FBFood *_food
}

- (FBFood *)food
{
    return _food;
}

- (void)setFood:(FBFood *)food
{
    _food = food;
}

@end
           

注:weak隻能修飾oc類property

unsafe_unretained

@interface FBAnimal : NSObject

@property (unsafe_unretained) FBFood *food;

@end

@implementation FBAnimal

@end
           
- (void)arc_unsafe_unretained
{
    FBFood *food = [[FBFood alloc] init];
    
    FBAnimal *animal = [[FBAnimal alloc] init];
    animal.food = food;
    
    NSLog(@"source: food = %p", food);
    NSLog(@"property: food = %p", animal.food);
    
    food = nil;
    
    NSLog(@"source: food = %p", food);
    NSLog(@"property: food = %p", animal.food);
}
           

output:

source: food = 0x7fd3b8c11c30
property: food = 0x7fd3b8c11c30
dealloc FBFood
source: food = 0x0
(lldb)
           

unsafe_unretained property food在implementation中合成以下Method定義

@implementation FBAnimal
{
    __unsafe_unretained FBFood *_food
}

- (FBFood *)food
{
    return _food;
}

- (void)setFood:(FBFood *)food
{
    _food = food;
}

@end
           

注1:unsafe_unretained既可修飾非oc類property,也可修飾oc類property 注2:unsafe_unretained修飾非oc類同assign 注3:如果unsafe_unretained property指向的instance object已經dealloc,則通路該unsafe_unretained property會crash

retain

@interface FBAnimal : NSObject

@property (retain) FBFood *food;

@end

@implementation FBAnimal

@end
           
- (void)arc_retain
{
    FBFood *food = [[FBFood alloc] init];
    
    FBAnimal *animal = [[FBAnimal alloc] init];
    animal.food = food;
    
    NSLog(@"source: food = %p", food);
    NSLog(@"property: food = %p", animal.food);
    
    food = nil;
    
    NSLog(@"source: food = %p", food);
    NSLog(@"property: food = %p", animal.food);
}
           

output:

source: food = 0x7f9a5ad1a060
property: food = 0x7f9a5ad1a060
source: food = 0x0
property: food = 0x7f9a5ad1a060
dealloc FBFood
           

retain property food在implementation中合成以下Method定義

@implementation FBAnimal
{
    __strong FBFood *_food
}

- (FBFood *)food
{
    return _food;
}

- (void)setFood:(FBFood *)food
{
    _food = food;
}

@end
           

注:ARC下retain同strong

總結

  • copy:MRC與ARC下無差別,隻能修飾oc類property,本質調用oc類copy,是以oc類必須遵守NSCopying
  • MRC特有:retain,隻能修飾oc類property
  • ARC特有:strong,weak,隻能修飾oc類property
  • MRC為了相容ARC,MRC下strong同retain,weak禁用,因為MRC下沒有ARC下weak對應使用方式
  • ARC為了相容MRC,retain同strong
  • assign:既可修飾非oc類property,也可修飾oc類property,ARC下,修飾oc類property同unsafe_unretained
  • unsafe_unretained:既可修飾非oc類property,也可修飾oc類property,MRC下同assign,修飾非oc類同assign