关于声明控件用weak和strong的问题&NSString用copy好还是strong

1、控件声明strong好还是weak?

相信很多人都被这个问题困惑过,我也不例外,所以做下总结,希望能帮到大家,有不对的欢迎拍砖!

以创建一个lable为例,在storyboard里用拖线的方式创建时,系统默认的使用weak修饰(同时用IBOutlet修饰)

<span style="font-family:Microsoft YaHei;font-size:12px;">@property (weak, nonatomic) IBOutlet UILabel *label;</span>
用代码创建lable时,对于strong的方式:

<span style="font-family:Microsoft YaHei;font-size:12px;">@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];
}</span>

用wak修饰时,需要先创建一个label,最后再把label 赋值给self.label

<span style="font-family:Microsoft YaHei;font-size:12px;">@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;
}</span>

查找了一些资料,发现主要原因是,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 的区别

<span style="font-family:Microsoft YaHei;font-size:12px;">@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);
}</span>
打印输出结果为

<span style="font-family:Microsoft YaHei;font-size:12px;"></span><p class="p1"><span class="s1"><strong>2015-11-22 12:23:42.464 autolayout[4744:345705] ======cString:123   sString:123=====</strong></span></p><p class="p1"><span class="s1"><strong>2015-11-22 12:23:42.465 autolayout[4744:345705] ======cString:123   sString:123456=====</strong></span></p>
mutableString的值改变了,用strong修饰的时候,strongString的值也跟着改变了,因为strongString和mutableString指向相同的内存地址;用copy修饰NSString的时候是浅复制,相当于把mutableString内存复制了一份给了copyedString,它们两个指向的内存并不相同,当mutableString的内存地址发生改变时并不会影响copyedString的值;

如果是将NSString *string赋值给 self.copyedString,self.strongString 的情况下,用strong和weak没有区别,个人习惯用copy。

一句话:如果希望你是的sting要跟着赋值给你的那个string 改变,就用strong;如果希望你的sting保持不变,用weak;一般情况下都是希望string保持不变的,所以大部分情况用的是copy。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值