iRSSの日記

はてなダイアリーiRSSの日記の続き

「基礎からのiPhoneSDK」解りやすくて、うれしいです。

iPhoneSDKを理解したくて、再勉強中。

基礎からのiPhone SDK

基礎からのiPhone SDK


メモリ管理の仕組みとかが、丁寧に説明されていて、すばらしいです。

204Pのタイムゾーン指定のメソッドでの疑問

ヘッダで、インスタンス変数として定義されている

    NSTimer*     timer;             // 時計更新用タイマー 
    NSTimeZone*  timeZone;          // タイムゾーン 

実装のほうは

- (id) init {
    
    // 1 スーパークラスによる初期化
    self = [ super init ];
    
    if ( self != nil ) { 
        
        // 2 timerの生成
        timer = [ NSTimer scheduledTimerWithTimeInterval: 1.0f
                                                  target: self 
                                                selector: @selector( updateClock: )
                                                userInfo: nil 
                                                 repeats: YES ];
        
        // 3 timeZoneの生成
        timeZone = [ [ NSTimeZone systemTimeZone ] retain ];
        
    } 
    
    // 4 初期化したインスタンスを返す
    return( self ); 
}

NSTimer scheduledTimerWithTimeIntervaで生成した、timerオブジェクトはretainしていないのはどうしてかなあとおもったら、作者鶴薗賢吾さんのcocoaNoteに書かれてました。

補足 : [ +NSTimer scheduledTimerWithTimeInterval : target : selector : userInfo : repeats : ] で生成したタイマーは、Cocoaフレームワーク側が保持 ( retain ) しているため、繰り返しの指定がなければ、セレクタが実行された後に破棄されますし、繰り返しの指定がある場合は、[ -NSTimer invalidate ] によって停止されたときに破棄されます。そのため、タイマー生成後に retain する必要はありません。

- (void) dealloc {
    
    // 1 タイマーとタイムゾーンを破棄
    [ timer release ];
    [ timeZone release ]; 
    
    // 2 残りの部分はスーパークラスで破棄
    [ super dealloc ]; 
    
}

しかし、deallocではtimer releaseしているは、どうしてだろう?

releaseではなくて、ここは、invalidateするのが正解なのかもしれません。

この NSTimer を削除する際に、
[m_timer release]:
このように、単に release しただけでは削除されず、タイマーも止まりません。
なぜかというと、メインループ(のスケジューラ)がこの NSTimer を参照しているからです。

ということで、解放する前には確実に invalidate してメインループから NSTimer を取り除いておきましょう。