dealloc不执行 ios_ios dealloc 不执行 - CSDN
  • iOS dealloc 不执行或延迟执行的问题 1)不执行dealloc  查看是不是循环引用造成的类销毁 2)延迟执行dealloc  本地在类撤销之前有延时操作,未执行完 比如: [self performSelector:@selector(xx) with...

    iOS dealloc 不执行或延迟执行的问题


    1)不执行dealloc 

    1.查看是不是循环引用造成的类不销毁

    2.调用其他类的时候查看有没有将本类中的对象传过去,例如self,self.tableview   

    传的时候注意使用weak,不要使用strong

    否则会造成当前类无法释放,dealloc不执行一直占用内存。

    今天好坑啊,偷懒用别人的代码,发现里面的有这个问题。

    3.performSelector 关于内存管理的执行原理是这样的执行

     [self performSelector:@selector(method1:) withObject:self.tableLayer afterDelay:3]; 的时候,系统会将tableLayer的引用计数加1,执行完这个方法时,还会将tableLayer的引用计数减1,由于延迟这时tableLayer的引用计数没有减少到0,也就导致了切换场景dealloc方法没有被调用,出现了内存泄露。 

    利用如下函数: 

    [NSObject cancelPreviousPerformRequestsWithTarget:self] 当然你也可以一个一个得这样用: 

    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(method1:) object:nil] 

    加上了这个以后,顺利地执行了dealloc方法  

    4.NSTimer使用造成的内存泄露。

    注意自己需要管理NSTimer停止与释放,否则,会一直运行,导致页面内存不释放。

    举个栗子: 在自定义View中,如果不手动停止NSTimer对象,那么会一直NSTimer会一直持有这个类,导致内存不释放,也就是内存泄露。

    解决方法:在controller中手动调用removeFromSuperView,重写- (void)removeFromSuperview 把_timer 停止释放。

    - (void)removeFromSuperview {

        [superremoveFromSuperview];

        [_timerinvalidate];

        _timer =nil;

    }



    2)延迟执行dealloc 

    本地在类撤销之前有延时操作,未执行完

    比如:

    [self performSelector:@selector(xx) withObject:nil afterDelay:10.0];



    暂时找到以上这几种情况。其他情况再续。。。

    展开全文
  • 问题描述最近在一个项目中用到了地图,发现在地图页面和上一个页面间反复切换回出现内存爆增的情况,就像吃了炫迈一样根本停下来(直到app内存爆表,app闪退收场)。造成这一结果的根本原因是地图的mapView没有...

    问题描述

    最近在一个项目中用到了地图,发现在地图页面和上一个页面间反复切换回出现内存爆增的情况,就像吃了炫迈一样根本停不下来(直到app内存爆表,app闪退收场)。造成这一结果的根本原因是地图的mapView没有释放,导致每次打开地图界面的时候内存中都重新加载了一个地图mapView。于是在网上搜索了一番找到了解决办法,只需要在地图的ViewController中dealloc方法中释放掉mapView就行了。具体代码如下:

    - (void)dealloc {
        [_mapView release];
        [super dealloc];
    }
    
    //并且在界面将要显示的时候设置代理,将要消失的时候取消代理
    - (void)viewWillAppear:(BOOL)animated {
        _mapView.delegate = self;
    }
    
    - (void)viewWillDisappear:(BOOL)animated {
        _mapView.delegate = nil;
    }
    
    

    以上给出的方法确实是对的,可以解决反复切换地图页面和地图上一级页面内存暴增造成的闪退问题。但是这里要说的不是这个问题,而是一个新的问题,我在dealloc中打了断点,但是dealloc根本就没有执行,所以mapView也就根本就没有释放,内存还是一样在暴增。为什么ViewController已经被pop了,而ViewController的dealloc方法却没有被调用?(按理说ViewController被pop的时候它的dealloc的方法应该被调用才对)。

    解决办法

    通过Google搜索终于在晚上找到了答案(大家就不要用百度,想要快速准确的找到自己想要的答案推荐大家用google)。造成ViewController不释放的原因可能有很多。遇到dealloc不调用的时候只需要检查您的ViewController中是否存在以下几个问题:

    1. ViewController中存在NSTimer

      如果你的ViewController中有NSTimer,那么你就要注意了,因为当你调用时,这个target:self就增加了ViewController的return count,如果你不将这个timer invalidate,将别想调用dealloc。

    [NSTimer scheduledTimerWithTimeInterval:1.0 
                                     target:self 
                                   selector:@selector(updateTime:) 
                                   userInfo:nil 
                                    repeats:YES];
    
    1. ViewController中有关的代理

      一个比较隐秘的因素,你去找找与这个类有关的代理,有没有强引用属性?比如一个代理的delegate应该是 assign 的现在是retain,(╯‵□′)╯︵┻━┻,就是这个,它会影响你不让你调用dealloc,不信,就试试吧。(这个我还没有遇到过)。

    2. ViewController中有Block

      这个就是我我上面不进入dealloc的真正原因,Block体内使用实例变量也会造成循环引用,使得拥有这个实例的对象不能释放。
      例如你这个类叫OneViewController,有个属性是NSString *name; 如果你在block体中使用了self.name,那样子的话这个类就没法释放。
      要解决这个问题,MRC下只需

    __block Viewcontroller *weakSelf = self;
    
    ARC下将__block 换为 __weak
    

    目前我所知道的就以上三种情况,如果有什么错误的地方或者还存在的一些情况,欢迎大家来补充。

    转载请注明出处,原文地址:http://jvaeyhcd.github.io/2016/04/06/iOS中造成dealloc不调用的原因/

    展开全文
  • ViewController 内没有timer 也没用使用retain的delegate。 初始化Push之后也release了。可是这方法就是走。。。求解。。
  • iOS开发中常见的造成dealloc不调用的原因 自己遇到的问题描述: 最近项目里要用到AVPlayer播放器,自己便写了一个简单的播放器,但是却遇到了一个很奇怪的问题,,在播放中途点击了关闭按钮,dismiss了...

    iOS开发中常见的造成dealloc不调用的原因

    自己遇到的问题描述:
    最近项目里要用到AVPlayer播放器,自己便写了一个简单的播放器,但是却遇到了一个很奇怪的问题,,在播放中途点击了关闭按钮,dismiss了VideoPlayerViewController,但是画面关闭了,声音一直还在,而且内存爆增。 后来几经发现才找到问题所在,是VideoPlayerViewController在dismiss的时候并没有被释放,从而导致引用的VideoPlayView没有走dealloc方法,进而导致AVPlayerItem调用了KVO回调方法之后没有被移除监听([self.currentItem removeObserver:self forKeyPath:@”status” context:nil];放在了dealloc方法里)。。从而开始寻找dealloc没有被释放的原因。

    总结方法:
    1.ViewController中存在NSTimer
    如果你的ViewController中有NSTimer,那么当你调用了

    NSTimer scheduledTimerWithTimeInterval:1.0 
                                     target:self 
                                   selector:@selector(updateTime:) 
                                   userInfo:nil 
                                    repeats:YES];

    这个target:self 就增加了ViewController的return count,如果你不使用[timer invalidate] 销毁计时器,那就不会走dealloc方法。

    2.ViewController中有Block
    Block体内使用实例变量也会造成循环引用,使得拥有这个实例的对象不能释放。 例如你这个类叫ViewController,有个属性是NSString *name; 如果你在block体中使用了self.name,那样子的话这个类就没法释放。
    要解决这个问题只需

    __weak typeof(self) weakself = self;

    3.ViewController中有关的代理
    这个就是我上面不走dealloc的真正原因,,,一个比较隐秘的因素,你去找找与这个类有关的代理,看有没有强引用属性?比如一个代理的delegate应该是 assign 的现在是retain,就是这个,它会影响你不让你调用dealloc。 我这里是因为VideoPlayerViewController里在建立URLSession会话的时候,使用了NSURLSession的代理,,这个代理是强引用的,session会话如果不主动取消,就会造成循环引用,导致内存泄漏。
    这里的解决办法:

    @interface VideoPlayerViewController () <NSURLSessionDelegate>
    @property (nonatomic, strong) NSURLSession *session; 
    @end
    //懒加载自定义文件下载的session,并设置代理
    - (NSURLSession *)session{
        if (_session == nil) {
            _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];  //这个代理是强引用的
        }
        return _session;
    }
    - (void)viewDidDisappear:(BOOL)animated {
        [super viewDidDisappear:animated];
    
        //在viewDidDisappear方法里手动关闭会话
        [self.session invalidateAndCancel];
    }

    这样就解决了一开始描述的那个问题了,,但是有一点要注意的是,session一旦被取消就无法再次使用。

    展开全文
  • 1.循环引用(多发生在对象有一个timer属性,返回时释放timer即可,先invalidate,再置为nil) 2.自定义的view(先removefromsuperview,再置为nil,即可调动view的dealloc方法)

    1.循环引用(block循环调用或者某对象有一个timer属性,返回时释放timer即可,先invalidate,再置为nil)

    2.自定义的view(先removefromsuperview,再置为nil,即可调动view的dealloc方法)

    3.代理没有置为nil(tableview和webview)

    4.performSelector方法导致dealloc延迟执行(通过cancelPreviousPerformRequestsWithTarget释放

    展开全文
  • 如果代码中存在NSTimer,当调用以下代码的时候,会增加ViewController的引用计数,需要在关闭页面的时候调用[timer invalidate] 销毁计时器,如果把[timer invalidate]放在了dealloc里,则永远不会被调用。...

    (1)NSTimer

    如果代码中存在NSTimer,当调用以下代码的时候,会增加ViewController的引用计数,需要在关闭页面的时候调用[timer invalidate] 销毁计时器,如果把[timer invalidate]放在了dealloc里,则永远不会被调用。

    [NSTimer scheduledTimerWithTimeInterval:1.0
                                     target:self
                                   selector:@selector(updateTime:)
                                   userInfo:nil
                                    repeats:YES];

    (2)Block

    Block体内使用实例变量也会造成循环引用(retain cycle)—— Block 会 retain ‘self’,而 ‘self’ 又 retain 了 Block,使得拥有这个实例的对象不能释放。 例如当前类有个属性是NSString *name; 如果在block体中使用了self.name,那样这个类就没法释放了。 

    要解决这个问题只需要在block之前做以下声明,然后在block体内用weakself代替self。

    __weak typeof(self) weakself = self;
    topView.OnNoticeSelect = ^{
        [weakself OnNoticeClick];
    };

    当 block 本身不被 self 持有,而被别的对象持有,同时不产生循环引用的时候,就不需要使用 weakself 了。

    举个例子:

    
    @interface TestViewModel : NSObject
    
    @property (nonatomic, strong) void(^OnTestBlock2)(void);
    
    - (void)OnTestBlock1:(void(^)(void))block;
    
    @end

    在另外一个类中引用下面方法的时候会提示循环引用的警告:Capturing 'self' strongly in this block is likely to lead to a retain cycle

        self.viewModel = [[TestViewModel alloc] init];
        [self.viewModel setOnTestBlock2:^{
            [self OnTest];
        }];
    

    而引用下面的方法则不会提示循环引用的警告,这个类也能正常的释放。

        self.viewModel = [[TestViewModel alloc] init];
        [self.viewModel OnTestBlock1:^{
            [self OnTest];
        }];

    常见的UIView动画,NSDictionary和NSArray的枚举器(enumerate),GDC,AFNetworking,Masonry等中的block不会发生循环引用,所以无需使用weakself。

    以下用法不会引起循环引用:

        [self.models enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            [self OnTest:obj];
        }];
        [UIView animateWithDuration:0.1 animations:^{
            [self OnTest];
        }];
        dispatch_async(dispatch_get_main_queue(), ^{
            [self OnTest2];
        });
        AFHTTPSessionManager *session = [AFHTTPSessionManager manager];
        [session GET:url parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            [self OnAFSuccess];
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            [self OnAFFailure];
        }];
        [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
            if (@available(ios 11.0,*)) make.edges.mas_equalTo(self.view.safeAreaInsets);
            else make.edges.mas_equalTo(self.view);
        }];

    (3)Delegate

    在声明delegate的时候需要设置成weak,如果是strong强引用,就不会调用dealloc。

    
    @property (nonatomic,weak)id<UIRefershCollectionViewDelegate> refreshDelegate;
    

     

    展开全文
  • 当我们继承类的时候,子类实例在构造的...在c/c++是如此,在objc中也是如此,在iOS开发中,我们会看到这样的代码: 1.- (void)init  2.{  3. self = [super init];  4. if (self) 5. {  6. //init 7. }
  • iOS dealloc方法没有调用
  • iOS pop dealloc方法

    2017-05-23 14:24:18
    在某些情况下 viewcontroller pop 了 但是没有被释放。 1.在block里 直接调用实例变量 例如: [self.webView ...这样会造成循环引用,导致其能被释放 应该 __weak EH_WebViewController* weakSelf
  • ios 使用引用计数管理内存,当出栈的时候所有的引用计数都会为0并销毁,这样才不会导致内存释放掉导致的内存暴增从未因此崩溃,所有要避免循环引用的发生以及NStimer,notification的释放
  • iOS 在 ARC 环境下 dealloc 的使用、理解误区
  • 一,可能情况: 1> timer 没有清楚 2> 循环引用 3>block引用了实例变量。 二,查找到结果竟是 1> 没有使用 property 创建的属性,默认是强引用,会造成循环引用. 2>... NSTimer ...
  • - (void)dealloc; 什么时候回调用dealloc? 1、这个类被release的时候会被调用; 2、这个对象的retain count为0的时候会被调用; 或者说一个对象或者类被置为nil的时候;
  • 1、对象什么时候dealloc? 当对象的引用计数减为0时候。 2、dealloc发生在哪个线程? #import "ViewController.h" @interface classTest : NSObject @end @implementation classTest - (void)dealloc{ ...
  • ios的viewcontroller生命周期是 init -> loadView -> viewDidLoad -> viewWillAppear -> viewDidAppear -> viewWillDisappear -> viewDidAppear -> viewDidUnload -> dealloc 当我们使用NSNotificationCenter方法,...
  • 继博客 iOS内存话题: performSelector 导致立即 dealloc 后, 今天讨论一下 NSTimer 导致内存无法释放的问题. 直接上例子. ViewController 中打开另一个 ViewController(LoginPage). LoginPage.m #import ...
  • 之前很少用block和delegate,由于页面比较复杂...上个同事跟我说是第三方的问题,改了,解释一下,第三方用的是讯飞的sdk,后来我下了一个讯飞的demo,并没有发现任何问题,然后就在自己项目里面找,发现viewControll
  • 几种原因: 1.代理声明应为weak,默认strong强引用会导致计数器加1,无法释放内存;应这样声明:@property (nonatomic, weak) SampleClass *sampleClass;2.NSTimer定时器未释放,会导致计数器加1,无法释放内存。...
1 2 3 4 5 ... 20
收藏数 13,406
精华内容 5,362
关键字:

dealloc不执行 ios