如果有错误的地方,请指正。
首先这里涉及到iOS的内存管理机制,大致来讲就是有申请就必定要有释放,在mrc状态下,如果使用alloc init等创建对象,其对象内部的引用计数器就会加1,你就必须要进行一次release,然后系统会在dealloc中自动释放。
assign--基础数据类型,简单赋值,引用计数器不变化。
retain--引用计数器加1,一般用于NSString和基础数据类型以外的类对象创建,他的含义是浅拷贝,也就是拷贝对象指针,但不拷贝内部内容,指针所指内容是一致的。
copy--引用计数器加1,一般用于nsstring,指深拷贝,也就是拷贝对象的内容和指针,消除旧对象。
strong--arc机制下的强指针引用,引用计数器加1,他的含义约等于retain。
weak-arc机制下的弱指针,所有指向这个对象的weak指针都将被置为nil,能避免因为意外释放而导致的carsh。
那么在一般声明控件时,假若是ib控件,则默认为weak状态,如果非ib状态下进行声明,则具体代码如下
@interface AController : UIViewController
{
__weak UIView *aView;
}
@end
@implementation AController
- (void) viewDidLoad
{
[super viewDidLoad];
UIView *view = [[UIView alloc]initWithFrame:CGRectZero];
[self.view addSubview:view];
aView = view;
}
@end
基本还用weak声明,因为Controller并不直接“拥有”控件,控件由它的父view“拥有”。使用weak关键字可以不增加控件引用计数,确保控件与父view有相同的生命周期。
控件在被addSubview后,相当于控件引用计数+1;父view销毁后,所有的子view引用计数-1,则可以确保父view销毁时子view立即销毁。weak的控件在removeFromSuperview后也会立即销毁,而strong的控件不会,因为Controller还保有控件强引用。
在控件addSubview后再对weak变量赋值,防止控件被立即释放。
下面再来个例子,比如为什么NSString一般用copy而不用retain或者strong。
例子是摘抄别人的,懒得再打
@property(retain,nonatomic)NSString*rStr;
@property(copy,nonatomic)NSString*cStr;
- (void)test:
{
NSMutableString*mStr = [NSMutableStringstringWithFormat:@"abc"];
self.rStr= mStr;
self.cStr= mStr;
NSLog(@"mStr:%p,%p", mStr,&mStr);
NSLog(@"retainStr:%p,%p",_rStr, &_rStr);
NSLog(@"copyStr:%p,%p",_cStr, &_cStr);
}
假如,mStr对象的地址为0x11,也就是0x11是@“abc”的首地址,mStr变量自身在内存中的地址为0x123;
当把mStr赋值给retain的rStr时,rStr对象的地址为0x11,rStr变量自身在内存中的地址为0x124;rStr与mStr指向同样的地址,他们指向的是同一个对象@“abc”,这个对象的地址为0x11,所以他们的值是一样的。
当把mStr赋值给copy的cStr时,cStr对象的地址为0x22,cStr变量自身在内存中的地址0x125;cStr与mStr指向的地址是不一样的,他们指向的是不同的对象,所以copy是深复制,一个新的对象,这个对象的地址为0x22,值为@“abc”。
如果现在改变mStr的值:
[mStrappendString:@"de"];
NSLog(@"retainStr:%@",_rStr);
NSLog(@"copyStr:%@",_cStr);
结果,
使用retain的字串rStr的值:@"abcde",
而使用copy的字串cStr的值:@"abc",
所以,如果一般情况下,我们都不希望字串的值跟着mStr变化,所以我们一般用copy来设置string的属性。
如果希望字串的值跟着赋值的字串的值变化,可以使用strong,retain。
注意:上面的情况是针对于当把NSMutableString赋值给NSString的时候,才会有不同,如果是赋值是NSString对象,那么使用copy还是strong,结果都是一样的,因为NSString对象根本就不能改变自身的值,他是不可变的。
所以总的来说,NSString本身是无所谓的,但是如果一个 NSString 指针指向了一个 NSMutableString的内存空间的话,如果使用 strong 修饰的话,如果你在别处修改这个值的话,那么原来的值也会改变。用 copy 是生成了一份新的内存空间,原值不会改变,所以一般使用copy就足够了,因为我们很少有需求能跟随字符串变化而变化的字符串。