第一种情况直接weak修饰后初始化,编译器会提示警告:Assigning retained object to weak property; object will be released after assignment,赋值后会被释放

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, weak) UIView *bview;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    self.view.backgroundColor = [UIColor whiteColor];
    self.bview = [[UIView alloc] init];
    NSLog(@"%@",self.bview);
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"点击屏幕后%@",self.bview);
}

@end

结果

2023-11-29 10:32:51.003871+0800 OCDemo[82234:2684446] (null)
2023-11-29 10:33:01.251990+0800 OCDemo[82234:2684446] 点击屏幕后(null)
第二种情况用weak修饰赋值

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, weak) UIView *bview;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    self.view.backgroundColor = [UIColor whiteColor];
    UIView *tempView = [[UIView alloc] init];
    self.bview = tempView;
    NSLog(@"%@",self.bview);
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"点击屏幕后%@",self.bview);
}

2023-11-29 10:36:17.927977+0800 OCDemo[82441:2688402] <UIView: 0x7f81ac704240; frame = (0 0; 0 0); layer = <CALayer: 0x600000a78340>>
2023-11-29 10:36:30.112701+0800 OCDemo[82441:2688402] 点击屏幕后(null)
第三种情况用weak修饰赋值后添加到view上

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, weak) UIView *bview;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    self.view.backgroundColor = [UIColor whiteColor];
    UIView *tempView = [[UIView alloc] init];
    self.bview = tempView;
    [self.view addSubview:self.bview];
    NSLog(@"%@",self.bview);
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"点击屏幕后%@",self.bview);
}

2023-11-29 10:38:46.851065+0800 OCDemo[82679:2691860] <UIView: 0x7faec2f0c010; frame = (0 0; 0 0); layer = <CALayer: 0x6000000ab800>>
2023-11-29 10:38:48.487691+0800 OCDemo[82679:2691860] 点击屏幕后<UIView: 0x7faec2f0c010; frame = (0 0; 0 0); layer = <CALayer: 0x6000000ab800>>
最后一种情况为啥不被释放呢,原因是当我们执行了addSubview:方法之后,后面的视图就会被放到这个subViews数组里,可以看到,这个数组使用copy修饰的,也就是说,这是强引用!正是这个原因,我们才能用weak来修饰一个控件。因此可以保持这个控件的引用计数不为0,就不会被释放掉了。

@property(nonatomic,readonly,copy) NSArray<__kindof UIView *> *subviews;
总结一下:一般情况用weak,strong都可以的,但是特殊的种情况如果创建一个view用weak修饰,没有add到其他view上,那这个view就没有和别的view有强引用关系,引用计数也没有+1,所以会被释放,反之换成strong修饰的话,它本身就引用计数+1了,不管有没有被add到其他view上都不会被释放,所以不想这么纠结就都用strong修饰吧
还有个问题解释一下,strong修饰本身引用计数+1,addSubView后又+1,虽然引用计数为2,但是当整个父视图被销毁的时候,这两个引用计数都会变成0,所以不会造成内存泄漏。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部