2015-10-12 16:30:42 qq342261733 阅读数 4027

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];



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

2018-04-25 16:54:20 zhouxiangyu666666 阅读数 342

1.  ViewController 中的有NStimer,在ViewController消失前没有将NStimer销毁,导致ViewController的引用计数不为0.

2.在Block或者delegate中有循环引用情况。

解决方法:__weak ViewController *weakSelf = self;

2012-06-18 16:59:17 musou_ldns 阅读数 22978

众所周知,iOS开发的时候,使用ARC的话,dealloc函数是不需要实现的,写了反而会出错。

但有些特殊的情况,dealloc函数还是需要的。

比如,在画面关闭的时候,需要把ViewController的某些资源释放,

在viewDidDissppear不一定合适,viewDidUnload一般情况下只在memory warning的时候才被调用。

不用ARC的情况下,我们自然会想到dealloc函数。

其实ARC环境下,也没有把dealloc函数禁掉,还是可以使用的。只不过不需要调用[supper dealloc]了。


举个例子,画面上有UIWebView,它的delegate是该画面的ViewController,在WebView载入完成后,需要做某些事情,比如,把indicator停掉之类的。

如果在WebView载入完成之前关闭画面的话,画面关闭后,ViewController也释放了。但由于WebView正在载入页面,而不会马上被释放,等到页面载入完毕后,回调delegate(ViewController)中的方法,由于此时ViewController已经被释放,所以会出错。(message sent to deallocated instance)

解决办法是在dealloc中把WebView的delegate释放。

-(void)dealloc {

    self.webView.delegate = nil;

}


2012-04-03 09:47:10 favormm 阅读数 8976

当我们继承类的时候,子类实例在构造的时候顺序是先高用父类的构造方法,再调用子类的构造方法。在c/c++是如此,在objc中也是如此,在iOS开发中,我们会看到这样的代码:

- (void)init
{
    self = [super init];
    if (self)
    {
        //init
    }

    return self;
}

看到没,初始化的时候都是先调用父类的初始化方法,为什么呢,因为父类更老,当然是先出生了。大笑,同样的情况可以在viewDidLoad中看到。


而销毁的时候则是相反的顺序,先销毁子类里分配的空间,再销毁父类的。如:

- (void)dealloc {
    [companion release];
    free(myBigBlockOfMemory);
    [super dealloc];
}

为什么会是这个顺序呢?因为长江后浪推前浪,子类是继承了父类的优点,发挥了自己长外, 敌人要想消灭对方,当然是先灭最强的,都说树大招风,就是这个道理。在销毁的时候如果不按这个顺序,有时候可能会crash。如在子类中应用了:

[outputStream setDelegate:self];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

如果dealloc写这成这样就会在removeFromRunLoop的时候crash:

- (void)dealloc {
    [super dealloc];
    if (outputStream) {
        [outputStream close];
        [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop]
                                forMode:NSDefaultRunLoopMode];
        [outputStream release];
        outputStream = nil;
    }
    delegate = nil;
}

如果写成这样就ok了:

- (void)dealloc {
    if (outputStream) {
        [outputStream close];
        [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop]
                                forMode:NSDefaultRunLoopMode];
        [outputStream release];
        outputStream = nil;
    }
    delegate = nil;
    [super dealloc]; // must be last!
}


在xCode version:4.2.1及以前版本中开发iOS的时候,如果将super dealloc写在子类dealloc中前面的时候是不会出错的,但在xCode version4.3.2中,它会有自动检测super dealloc的功能,如果写在前面,则会crash.


苹果官网也推荐这样写,请参看:https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/dealloc 中的特别注意事项中

Special Considerations
When garbage collection is enabled, the garbage collector sends finalize to the receiver instead of dealloc, and this method is a no-op.

If you are using manual reference counting, subclasses must implement their own versions of dealloc to allow the release of any additional memory consumed by the object—such as dynamically allocated storage for data or object instance variables owned by the deallocated object. After performing the class-specific deallocation, the subclass method should incorporate superclass versions of dealloc through a message to super









2017-04-17 16:43:27 georgehenrywilliam 阅读数 211
ios 使用引用计数管理内存,当出栈的时候所有的引用计数都会为0并销毁,这样才不会导致内存释放不掉导致的内存暴增从未因此崩溃,所有要避免循环引用的发生以及NStimer,notification的释放
没有更多推荐了,返回首页