当前位置: 移动技术网 > IT编程>移动开发>IOS > 【iOS开发】内存管理之UIViewController无法正常释放的常见问题

【iOS开发】内存管理之UIViewController无法正常释放的常见问题

2018年09月14日  | 移动技术网IT编程  | 我要评论

小哨兵官网,工会会员,幸福婚礼

引言

【ios开发】内存管理之uiviewcontroller无法正常释放的常见问题,ios开发中内存管理是很重要的,如果处理不当,轻则会导致内存泄漏、莫名其妙的bug等等,重则可能导致程序崩溃。本文总结了在ios开发中三个可能导致控制器不能正常释放的常见问题。

导致控制器不能正常释放的原因?

控制器的引用计数不为0,也就是说被其他对象强引用,因此不能正常释放。

如何知道控制器是否已经正常释放?

在arc模式下,控制器在彻底销毁之前会调用dealloc方法,并自动调用[super dealloc]方法。因此,可以重写基类的dealloc方法,输出控制器销毁提示信息,如果控制器没有调用dealloc方法,说明不能正常释放。

- (void)dealloc {
    nslog(@"%@ dealloc",nsstringfromclass([self class]));
}

问题一:block引发的循环引用

无弱引用声明的情况下,block持有它里面所有对象的所有权,即为强引用,所以当在block里面使用self的时候,可能会导致控制器不能正常释放。

比如:objectb拥有callbackblock属性,在objecta中设置该属性

[objectb setcallbackblock:^{
    [self excublock];
}];

在block中引用了自身方法(或变量),形成了循环引用。

解决方法:

在block中使用对自身对象的弱引用来替换self

__weak __typeof(self)weakself = self;
[objectb setcallbackblock:^{

    __strong __typeof(weakself)strongself = weakself;
    [strongself excublock];

}];

如果在block使用了成员变量,也要使用其弱引用,以 _datasource为例:

__weak typeof(_datasource) weakdatasource = _datasource;

问题二:强引用的delegate引发的循环引用

如果一个delegate属性的声明是strong的时候,会持有自身控制器的所有权,导致控制器不能正常释放。

比如:

customview的delegate声明

@property (nonatomic, strong) id delegate;
在控制器中赋值

self.customview.delegate = self;
这样,造成self对customview强引用,customview对self强引用,引发循环引用。

解决方法:

对代理使用弱引用

@property (nonatomic, weak) id delegate;

问题三:使用了nstimer没有销毁

当我们使用nstimer的方法

self.timer = [nstimer scheduledtimerwithtimeinterval:1.0 target:self selector:@selector(timeraction) userinfo:nil repeats:yes];
[[nsrunloop mainrunloop]addtimer:self.timer formode:nsrunloopcommonmodes];

时,定时器对象会对它的target(即self:当前控制器)持有强引用,如果定时器不销毁,则控制器无法释放。

解决方法:

在- (void)viewwilldisappear:(bool)animated或者- (void)viewdiddisappear:(bool)animated或者其他确定离开当前控制器的方法中销毁定时器。

- (void)viewdiddisappear:(bool)animated {
    [super viewdiddisappear:animated];
    if (self.timer != nil) {
        [self.timer invalidate];
        self.timer = nil;
    }
}

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网