创建测试类
@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; // 简单的赋值,什么都没有改变
}