欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

weak和strong限定在strongboard和xib中的使用

程序员文章站 2022-03-09 20:08:26
...

有的成员变量用weak,可是一样能达到strong的效果,是为什么呢?

storyboard和xib里面建立的控件,并且连线生成的成员变量可以用weak

关于一个控件生成的成员变量,例如一个@property (weak, nonatomic) IBOutlet UILabel *label1;之所以能用weak
简单来说当,storyboard和xib上面建立的控件,然后再连线带.m类文件上的成员变量,可以用weak是因为,storyboard和xib上面建立的控件,是被storyboard和xib指向,是一个强指向,在arc中有强引用指向就等于是strong,相当于MRC给label1引用计数+1.所以,就算这个时候成员变量是weak,因为有强指针引用,就变成了strong。这样在当一个方法内结束,比如在init方法中给label1赋值,init方法结束,label1并不会变成nil,因为他此时是strong,所以不释放。如果当storyboard和xib被销毁的时候,那么ARC中指向label1的强指针就撤销,MRC中label1引用计数-1,就等于0,那么label1这个时候label1=nil被释放

在storyboard和xib生成的view没释放之前,weak和strong限定的成员变量页都不会被释放,都是strong,这个时候weak和strong没区别。

不是storyboard 和xib生成的变量用weak如果用addSubview也能得到保存,因为addSubview,会建立一个强指针引用,把weak变成了strong

addSubView的xcode快速帮助说明中提到:
This method establishes a strong reference to view and sets its next responder to the receiver, which is its new superview.
这个方法对视图建立一个强引用,并且把接收者设置为它的下一个响应者,也是它的新的父类view。
在ARC中,只要有一个强指针指向对象,那么这个对象就不会被释放,就是strong了。所以weak控件被 addSubView以后相当于变成了strong

下面的代码:

#import "TDWShopView.h"
@interface TDWShopView()
@property (weak, nonatomic)  UILabel *label2;
@end

@implementation TDWShopView

- (void)showLabel2
{
    
    UILabel *templabel=[[UILabel alloc]init];
    templabel.frame=CGRectMake(100, 100, 100, 100);
    templabel.text=@"我是label2";
    templabel.backgroundColor=[UIColor redColor];
    _label2=templabel;
    //之所以用一个临时对象创建,是因为templabel是默认的指针限定,默认就是__strong强指针,强指针可以接收创建的对象,__weak弱指针接收创建对象会立即释放
    
   [self addSubview:_label2];//这里执行了addSubview,所以label2变成了strong,当这里结束以后,label2依然保存着值,到了,
    
}

- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        [self showLabel2];
        NSLog(@"_label2.text=%@",_label2.text);
        //这里会输出_label2.text=我是label2 
        
    }
    return self;
}

  • 有 addSubview的输出结果:_label2.text=我是label2
  • 没有 addSubview的输出结果:_label2.text=(null)

weak成员变量不能直接被用来接收 alloc init创建对象,对象会立即被释放,相当于__weak 对象不能创建对象一样,否个什么都接收不到.同样是上面的代码

 __weak UILabel *templabel=[[UILabel alloc]init];
 //只在最前面加了__weak弱指针的想定,这样templabel什么都接收不到,对象创建后会被立即释放。

@property (weak, nonatomic) UILabel *label2;//相当于__weak UILabel *label2

@interface TDWShopView()
@property (weak, nonatomic)  UILabel *label2;
@end

@implementation TDWShopView

- (void)showLabel2
{
    
    _label2=[[UILabel alloc]init];//这里因为_label2是weak弱指针,对象创建后会立即释放
    _label2.frame=CGRectMake(100, 100, 100, 100);
    _label2.text=@"我是label2";
    _label2.backgroundColor=[UIColor redColor];
    
   [self addSubview:_label2];//添加不上控件,因为_label2是weak弱指针接收创建对象的时候立即释放,=nil。所以addSubview加载的是一个nil空指针。