常用的 Attributes 有:
- 读写属性 (readwrite/readonly)
- setter语意 (assign/retain/copy/strong/weak)
- 原子性 (atomic/nonatomic)
assign 是直接赋值,当变量release 时, 该声明的成员变量将会无效.
retain/strong 是在赋值时,将变量的引用计数 +1, 当此类释放此成员变量时,该变量的引用计数 -1
copy 当前类持有该成员变量,与其它变量的内存变量不一样
assign 和 retain 的区别
简单的说, 当你把变量 A 赋值给 属性为 assign 的变量assignStr 时候, A的引用计数没有增加,这样一来虽然 assignStr 引用了 变量A ,它的计数根本没有增加,这样当变量A 被自动释放时,这个时候 assignStr 就会报错. 另外是 retain, 当把变量A
赋值给 属性为 retain(strong) 的变量strongStr 时候, A的引用计数+1了,这样只要 strongStr 没有被释放,A 是不会被释放的,即任何时候调用 strongStr 都是没有问题的.
下面的代码是测试 assign 和 retain 的区别:
1. 变量声明
2. 调用 createStr 方法分别给两个方法赋值
3. 输出 strongStr 和 assignStr的值,结果是输出 assignStr 时报错
注意: 如果直接 调用 createStr 然后再调用 timeAction 这样是不会报错的,因为两个方法在同一个 runloop 里面,也就是说在createStr 方法里面的str1 和 str2 没有被释放,这样的话输出时当然不会有问题了. 使用 @autoreleasepool 或者 开一个新的线程就是为了提前释放 str1 和 str2 以达到我们测试的效果.
变量声明
@property
(
strong
,
nonatomic
)
NSString
*stongStr;
@property
(
assign
,
nonatomic
)
NSString
*assignStr;
|
相关输出log方法
- (
void
)createStr {
NSString *str1 = [[ NSString alloc ] initWithFormat : @"stong str%d" , arc4random () % 11 ]; NSString *str2 = [[ NSString alloc ] initWithFormat : @"assign str%d" , arc4random () % 11 ]; self . stongStr = str1; self . assignStr = str2; NSLog ( @"%@" , self . stongStr ); NSLog ( @"%@" , self . assignStr ); } - ( void )timeAction { NSLog ( @"%@" , self . stongStr );
NSLog(@"%@",self.assignStr);
//
输出报错
}
|
相关测试方法
@autoreleasepool
{
[ self createStr ]; }
[self timeAction];
|
或
[
self
createStr
];
dispatch_async ( dispatch_get_main_queue (), ^{ [ self timeAction ];
});
|
strong 与retain (apple 官方解释)
— 完 2015年7月22日 下午4:57