- 本文乃己之拙见,欢迎指正,转载请注明出处。
例子1:
- 新建了一个继承自UIView的子类ZZYView,新增了一个属性zzyText,重写了它的dealloc方法,我想看看ZZYView什么时候释放?
@property (nonatomic,copy)NSString *zzyText; // 属性
@implementation ZZYView
// 重写Dealloc并打印数据
-(void)dealloc
{
NSLog(@"%@----%s",self.zzyText,__func__);
}
@end
- 在控制器ViewController中,我写了如下代码
#import "ViewController.h"
#import "ZZYView.h"
@interface ViewController ()
@property (nonatomic,weak)ZZYView *weakZView; //弱引用
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_weakZView = [[ZZYView alloc] initWithFrame:self.view.frame];
NSLog(@"ZZZZZ");
_weakZView.zzyText = @"例子1_weakZView";
_weakZView.backgroundColor = [UIColor redColor];
[self.view addSubview:_weakZView];
}
- 运行后打印如下,并有警告“Assigning retained object to weak variable; object will be released after assignment”
2017-02-15 13:47:34.513206 yinyong[3233:1042628] (null)-----[ZZYView dealloc]
2017-02-15 13:47:34.513326 yinyong[3233:1042628] ZZZZZ
-
总结:我们会发现_weakZView根本就没有被添加到self.view上面,在用alloc init分配内存初始化对象之后,这个对象被一个weak型指针_myView弱引用,引用计数为0。 在执行完这句代码
_weakZView = [[ZZYView alloc] initWithFrame:self.view.frame]
之后,这个对象就被释放了,也就是说当weak指针指向的对象释放后,weak指针会自动被置空。所以(null)-----[ZZYView dealloc]
在ZZZZZ
之前先打印,上面的对zzyText赋值&设置backgroundColor& addSubview都是无效的,这时_weakZView已经为nil。 -
那我们在用weak前提下,怎么用才能使其成功的添加到self.view上面呢?请看例子2
例子2:
- 同例子1 类ZZYView的代码不变,我们把控制器ViewController中的代码改成如下:
#import "ViewController.h"
#import "ZZYView.h"
@interface ViewController ()
@property (nonatomic,weak)ZZYView *weakZView; //弱引用
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
ZZYView *zView = [[ZZYView alloc] initWithFrame:self.view.frame];
zView.zzyText = @"例子2_weakZView";
zView.backgroundColor = [UIColor redColor];
_weakZView = zView;
[self.view addSubview:_weakZView];
}
#pragma mark点击屏幕触发
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
if (self.weakZView) {
[self.weakZView removeFromSuperview];
}
}
-
相比例子1我们多了一个强引用的指针myView,并增加了一个touch事件。
-
总结:由于所有的实例变量和局部变量默认都是strong型指针,所以zView强引用了初始化的对象,而后_weakZView弱引用zView,又通过
[self.view addSubview:_weakZView]
控制器的subView又强引用了该对象。所以weakZView被成功的添加到self.view上面,并且在“viewDidLoad”这个代码块执行完之后,即使zView被释放了weakZView也没被释放(控制器的subView还强引用着它)。点击屏幕后调用了[self.weakZView removeFromSuperview]
,weakZView被释放,打印如下
2017-02-15 14:49:41.271127 yinyong[3268:1051053] 例子2_weakZView-----[ZZYView dealloc]
例子3
- 我们再看看如果用strong会是个什么情况,同例子1 类ZZYView的代码不变,我们把控制器ViewController中的代码改成如下:
#import "ViewController.h"
#import "ZZYView.h"
@interface ViewController ()
@property (nonatomic,strong)ZZYView *strongZView; //弱引用
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
ZZYView *zView = [[ZZYView alloc] initWithFrame:self.view.frame];
zView.zzyText = @"例子3_strongZView";
zView.backgroundColor = [UIColor redColor];
_strongZView = zView;
[self.view addSubview:_strongZView];
/*
也可以简化这么写
_strongZView = [[ZZYView alloc] initWithFrame:self.view.frame];
zView.zzyText = @"例子3_strongZView";
zView.backgroundColor = [UIColor redColor];
[self.view addSubview:_strongZView];
*/
}
#pragma mark点击屏幕触发
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
if (self.strongZView) {
[self.strongZView removeFromSuperview];
}
}
- 总结:strongZView被成功添加到self.view上面,但是和例子2不同的是,点击屏幕后调用了removeFromSuperview,strongZView从界面上移除了不再显示,但strongZView并没被释放。当控制器ViewController被销毁时,触发了ZZYView的dealloc打印了下面的内容。
2017-02-15 14:49:46.271127 yinyong[3268:1051053] 例子3_weakZView-----[ZZYView dealloc]
因为ViewController被销毁,其属性strongZView也被销毁,strongZView指针指向的对象引用计数为0也会被释放。
网友评论