RAII in Objective-C with ARC

最近のObjective-CARCというオブジェクトポインタをスマートポインタにする機能があり、これのおかげでiPhoneアプリの開発ではRAIIができる。つまり、不要になったオブジェクトはその瞬間にデストラクタ(-dealloc)が呼ばれるため、デストラクタ内でリソースの開放を行なえる。

// デバイスのネットワークインジケータをRAIIで制御する

@interface NetworkActivityGuard : NSObject
@end

@implementation NetworkActivityGuard

- (id)init // コンストラクタ
{
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
    return [super init];
}

- (void)dealloc // デストラクタ
{
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];    
}

@end

使い方:

-(void)foo
{
    // ネットワークインジケータを表示する
    NetworkActivityGuard *guard = [[NetworkActivityGuard alloc] init];

    // 処理をする (ここでは単に2秒後にクロージャを呼ぶ)
    double delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_current_queue(), ^(void){
        // このブロックに変数をバインドしてクロージャにするため、
        // guardをかならずブロック内で参照する必要がある!
        (void)guard;

        // このクロージャが破棄されるとき
        // guardのリファレンスカウンタもひとつ減る
        // 他にguardを参照しているものがなければ
        // [guard dealloc] が呼ばれる
    });
}

エキスパートObjective-Cプログラミング ?iOS/OS Xのメモリ管理とマルチスレッド?

エキスパートObjective-Cプログラミング ?iOS/OS Xのメモリ管理とマルチスレッド?