zoukankan      html  css  js  c++  java
  • 问题:viewController不会调用dealloc()不会销毁

    问题

    在调试程序时,我从ViewController A push进 ViewController B,在从B back时发现程序不会执行B里面的dealloc(),很诡异的问题,因为按理说此时点击back是执行pop操作的,是会执行dealloc()函数的,但经调试发现确实没有执行。所以viewController也就不会销毁.

    原因

    The dealloc method was not being called if any of the references held by a viewcontroller were still in memory. 也就是说,我当前View B 内存中计数器不为0,还有一些内容的引用计数不为0, 所以造成了 controller 不能及时释放.

    解决

    我发现在我的代码里有一个倒计时的计时器的功能, 是通过 NSTimer实现的, 
    在调用的时候对 target:self 进行了retain, 这时候你pop回上一级,self的引用计数还剩1,所以肯定不会dealloc. 当其倒计时结束后, 我有一个[timer invalidate]的方法, 这个时候才会调用 dealloc.  
    所以我的解决办法是在viewWillDisappear: 方法中执行[timer invalidate];这样,self view计数器为0,当前view就会自动调用delloc()。

    总结

    其实这个问题, 就跟循环引用的问题是类似的, 都是由于内存考虑不周全管理不当造成的. 但是很多时候都会出现, 尤其是在 NSTimer , block , delegate, 使用的时候, 很容易造成当前页面不能及时销毁, 从而导致内存泄露. timer 一定要及时invalidate, block 要用 copy修饰而且还有防止析构和 block块内的循环引用, delegate 要用assign 修饰. 等等都需要好好注意.

    controller 不能释放,不走dealloc方法的4种可能

    第一种: controller中使用了计时器 NSTimer 使用后没有销毁 导致循环引用

    self.playerTimer = [NSTimerscheduledTimerWithTimeInterval:1target:selfselector:@selector(playProgressAction)userInfo:nilrepeats:YES];

    使用后记得销毁

     
    
       [_playerTimerinvalidate];
    
        _playerTimer =nil;

    第二种:协议delegate 应该使用weak修饰,否则会引起循环引用 不能释放内存

    @property (nonatomic,weak)id<huifuDelegate>huifudelegate;

    第三种:使用到block的地方,,block回调中不能直接使用self 否则可能引起循环引用。

     
    
       __weaktypeof(self) weakSelf =self;
    
        _audioStream.onCompletion=^(){
    
            [weakSelf nextButtonAction];
    
        };

    第四种:

    对于前三种 大家可能都知道,,我发现一个会导致controller不能释放的情况,,很诡异,,pop后不走dealloc  再push进来会走一次dealloc..这种情况是我接手的工程中出现的问题,,不仅不能释放 ,,如果这个controller中有音频 视频的录制,,应用退入后台会出现麦克风后台使用的提示。。如果有使用AirPlay 播放音频 ,,也会对AirPlay的时间显示产生干扰。。当然这都是没释放内存引起的。。。。。。。

    具体的情况如下,

    有ViewController和ceshiViewController   ViewController要push到ceshiViewController

    #import "ViewController.h"
    
    #import "ceshiViewController.h"
    
     
    
    @interfaceViewController (){
    
        ceshiViewController *ceshiVC;// 使用实例变量声明的时候,,我是不怎么这样写
    
    }
    
     
    - (void)action{
    
        ceshiVC =  [[ceshiViewControlleralloc]init];///这样写就出问题了
    
        [self.navigationControllerpushViewController:ceshiVCanimated:YES];
    
    }
    
    /////////////==============///////////////////
    
     
    
    #import "ceshiViewController.h"
    
     
    
    @interfaceceshiViewController ()
    
     
    
    @end
    
     
    
    @implementation ceshiViewController
    
    - (void)dealloc{
    
        NSLog(@"---释放");
    
     
    
    }

    controller 返回后不会释放。。。。。。。。

    5.。。。。项目中遇到的不走dealloc情况

     
    
    @interface TopicDetailViewController (){
    
     
    
        NSInteger videoType;
    
    }
    
     
    
    - (void)addFooterData{
    
      __weak TopicDetailViewController *weakself = self;
    
        self.TopicDetailTableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
    
            [weakself loadDataWithtype:videoType];  
    
            /// 在这里使用videoType后 不走dealloc 换成属性创建,,使用weakself.videoType 可解决
    
        }];
    
    }
  • 相关阅读:
    1058 A+B in Hogwarts (20)
    1046 Shortest Distance (20)
    1061 Dating (20)
    1041 Be Unique (20)
    1015 Reversible Primes (20)(20 分)
    pat 1027 Colors in Mars (20)
    PAT 1008 Elevator (20)
    操作系统 死锁
    Ajax的get方式传值 避免& 与= 号
    让IE浏览器支持CSS3表现
  • 原文地址:https://www.cnblogs.com/henusyj-1314/p/8533198.html
Copyright © 2011-2022 走看看