retain OR assign


retain OR assign_第1张图片
天马

创建测试类

@interface PropertyClass : NSObject

@property(assign,nonatomic)NSString *stringOne;

@property(retain,nonatomic)NSString *stringTwo;

@end

retain

        对其他NSObject和其子类对参数进行release旧值,再retain新值         指定retain会在赋值时唤醒传入值的retain消息。此属性只能用于Objective-C对象类型,不能用于基础数据类型跟 C数据类型。

    创建一个retain关键字修饰的属性。

@property(retain,nonatomic)NSString *stringTwo;

    根据打印这个属性的retainCount和地址来推理retain具体是怎么操作的,将创建的TestStr这个值赋予retain修饰的属性stringTwo

PropertyClass *testClass = [[PropertyClass alloc]init];

NSMutableString *TestStr = [[NSMutableString alloc]initWithFormat:@"test"];

NSLog(@"TestStr retainCount:%lu",(unsigned long)[TestStr retainCount]);

NSLog(@"TestStr address:%p",TestStr);

testClass.stringTwo = TestStr;

NSLog(@"TestStr retainCount:%lu",(unsigned long)[TestStr retainCount]);

NSLog(@"testClass.stringTwo retainCount:%lu",(unsigned long)[testClass.stringTwo retainCount]);

NSLog(@"testClass.stringTwo address:%p",testClass.stringTwo);

NSLog(@"TestStr address:%p",TestStr);

    打印结果:

2018-01-29 02:20:50.387128+0800 PropertyTest[5106:938391] TestStr retainCount:1

2018-01-29 02:20:50.387308+0800 PropertyTest[5106:938391] TestStr address:0x60400024c0c0

2018-01-29 02:20:50.387439+0800 PropertyTest[5106:938391] TestStr retainCount:2

2018-01-29 02:20:50.387566+0800 PropertyTest[5106:938391] testClass.stringTwo retainCount:2

2018-01-29 02:20:50.387846+0800 PropertyTest[5106:938391] testClass.stringTwo address:0x60400024c0c0

2018-01-29 02:20:50.388024+0800 PropertyTest[5106:938391] TestStr address:0x60400024c0c0

    从以上结果可以看出,创建的TestStr的内存地址为0x60400024c0c0,retainCount = 1 ,将TestStr的值付给testClass.stringTwo以后,testClass.stringTwo以及TestStr打印的内存地址为0x60400024c0c0,retainCount = 2 ,得到的结果证实只是retainCount + 1。其他的没有改变,由此推断的结论。

 - (void)setStringTwo:(NSString *)stringTwo{

    if(_stringTwo != stringTwo){

        [_stringTwo release];        //将旧的值先release掉

        _stringTwo = [stringTwo retain]; //再将新的值赋予给stingTwo,而最后本类_stringTwo的retainCount是输入值stringTwo的retainCount,内存地址是输入值stringTwo的内存地址

    }

}

assign

        简单的赋值操作,不会改变引用计数,适用于基础数据类型(NSUInteger CGFloat)等和C数据类型(int float char long)。

    创建一个assign关键字修饰的属性。

@property(assign,nonatomic)NSString *stringOne;

        根据打印这个属性的retainCount和地址来推理assign具体是怎么操作的,将创建的TestStr这个值赋予assign修饰的属性stringOne

PropertyClass *testClass = [[PropertyClass alloc]init];

NSMutableString *TestStr = [[NSMutableString alloc]initWithFormat:@"test"];

NSLog(@"TestStr retainCount:%lu",(unsigned long)[TestStr retainCount]);

NSLog(@"TestStr address:%p",TestStr);

testClass.stringOne = TestStr;

NSLog(@"%lu",(unsigned long)[TestStr retainCount]);

NSLog(@"%lu",(unsigned long)[testClass.stringOne retainCount]);

NSLog(@"testClass.stringOne address:%p",testClass.stringOne);

NSLog(@"TestStr address:%p",TestStr);

    打印的结果:

2018-01-29 02:46:13.162875+0800 PropertyTest[5427:1038511] TestStr retainCount:1

2018-01-29 02:46:13.163090+0800 PropertyTest[5427:1038511] TestStr address:0x6040000539b0

2018-01-29 02:46:13.163223+0800 PropertyTest[5427:1038511] TestStr retainCount: 1

2018-01-29 02:46:13.163344+0800 PropertyTest[5427:1038511] testClass.stringOne retainCount: 1

2018-01-29 02:46:13.163608+0800 PropertyTest[5427:1038511] testClass.stringOne address:0x6040000539b0

2018-01-29 02:46:13.163730+0800 PropertyTest[5427:1038511] TestStr address:0x6040000539b0

        从以上结果可以看出,创建的TestStr的内存地址为0x6040000539b0,retainCount = 1 ,将TestStr的值付给testClass.stringOne以后,testClass.stringOne以及TestStr打印的内存地址为0x6040000539b0,retainCount = 1 ,得到的结果证实retainCount没变。内存地址没有改变,由此推断的结论。

- (void)setStringOne:(NSString *)StringOne{

    _stringOne = StringOne;      // 简单的赋值,什么都没有改变

}

你可能感兴趣的:(retain OR assign)