search
LoginSignup
21

More than 5 years have passed since last update.

iOSの、画面遷移時のメモリリークが止まらなかった話

先日、画面遷移時にメモリが開放されず、徐々にメモリ利用率が上昇する現象に苦しまされた。
Instrumentsで調べてみても、リークは見られなかった。何が問題だったのか。それはdispatch_afterを用いたループするアニメーションだった。

f:id:jeffsuke:20141002085323p:plain

dispatch_afterや、NSRunLoopNSTimer等を用いてループ処理を実行していると、ownerとなるオブジェクトが解放されようとしても、これらのオブジェクトが強参照するために、解放されないようだ。

今回実装していた物

UIImageViewのカスタムクラスの上に、UIImageが乗っており、animationImagesNSTimerによって、フェードイン・アウトするアニメーションの挙動を実装した。
参考:iphone fading of images

f:id:jeffsuke:20141002085957g:plain

元々の実装

これだと、ループが回り続け、ownerのオブジェクトは永遠に開放されない


NSTimer *timer = [NSTimer timerWithTimeInterval:4.0 
                                              target:self 
                                            selector:@selector(onTimer) 
                                            userInfo:nil 
                                             repeats:YES];

    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    [timer fire];

対策後

NSTimerをpropertyとして持ち、Viewが消える時に、invalidateし、解放する必要がある。

@interface JSKSwipeViewController ()
@property (nonatomic) NSTimer *timer;
@end

@implementation JSKSwipeViewController
- (void)startAnimation
{
    _timer = [NSTimer timerWithTimeInterval:4.0
                                     target:self
                                   selector:@selector(onTimer)
                                   userInfo:nil
                                    repeats:YES];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];

    // stop animation and release
    [self.timer invalidate];
    self.timer = nil;

}

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
21