1、控件声明strong好还是weak?
以创建一个lable为例,在storyboard里用拖线的方式创建时,系统默认的使用weak修饰(同时用IBOutlet修饰)
@property (weak, nonatomic) IBOutlet UILabel *label;
用代码创建lable时,对于strong的方式:
@interface ViewController ()
@property (nonatomic,strong) UILabel *label;
@end
@implementation ViewController
- (void)viewDidLoad {
self.label = [[UILabel alloc] initWithFrame:CGRectMake(50, 100, 50, 20)];
[self.view addSubview:self.label];
}
用wak修饰时,需要先创建一个label,最后再把label 赋值给self.label
@interface ViewController ()
@property (nonatomic,weak) UILabel *label;
@end
@implementation ViewController
- (void)viewDidLoad {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50, 100, 50, 20)];
[self.view addSubview:label];
self.label = label;
}
查找了一些资料,发现主要原因是,controller需要拥有它自己的view(这个view是所以子控件的父view),因此viewcontroller对view就必须是强引用(strong reference),得用strong修饰view。对于lable,它的父view是view,view需要拥有label,但是controller是不需要拥有label的。如果用strong修饰,在view销毁的情况下,label还仍然占有内存,因为controller还对它强引用;如果用wak修饰,在view销毁的时label的内存也同时被销毁,避免了僵尸指针出现。
用引用计数回答就是:因为Controller并不直接“拥有”控件,控件由它的父view“拥有”。使用weak关键字可以不增加控件引用计数,确保控件与父view有相同的生命周期。控件在被addSubview后,相当于控件引用计数+1;父view销毁后,所有的子view引用计数-1,则可以确保父view销毁时子view立即销毁。weak的控件在removeFromSuperview后也会立即销毁,而strong的控件不会,因为Controller还保有控件强引用。
总结归纳为:当控件的父view销毁时,如果你还想继续拥有这个控件,就用srtong;如果想保证控件和父view拥有相同的生命周期,就用weak。当然在大多数情况下用两个都是可以的,我个人习惯还是用weak。
使用weak的时候需要特别注意的是:先将控件添加到superview上之后再赋值给self,避免控件被过早释放。
2、声明NSString时用strong还是copy?
用一段代码就知道使用strong和copy 的区别
@interface ViewController ()
@property (nonatomic, copy) NSString *copyedString;
@property (nonatomic,strong) NSString *strongString;
@end
@implementation ViewController
- (void)viewDidLoad {
NSMutableString *mutableStirng = [NSMutableString stringWithString:@"123"];
self.copyedString = mutableStirng;
self.strongString = mutableStirng;
NSLog(@"======cString:%@ sStrong:%@=====",self.copyedString,self.strongString);
//改变mutableString的值,打印输出 self.copyedString,self.strongString
[mutableStirng insertString:@"456" atIndex:3];
NSLog(@"======cString:%@ sStrong:%@=====",self.copyedString,self.strongString);
}
打印输出结果为
======cString:123 sString:123=====
======cString:123 sString:123456=====
mutableString的值改变了,用strong修饰的时候,strongString的值也跟着改变了,因为strongString和mutableString指向相同的内存地址;用copy修饰NSString的时候是浅复制,相当于把mutableString内存复制了一份给了copyedString,它们两个指向的内存并不相同,当mutableString的内存地址发生改变时并不会影响copyedString的值;
如果是将NSString *string赋值给 self.copyedString,self.strongString 的情况下,用strong和weak没有区别,个人习惯用copy。
一句话:如果希望你是的sting要跟着赋值给你的那个string 改变,就用strong;如果希望你的sting保持不变,用copy;一般情况下都是希望string保持不变的,所以大部分情况用的是copy。