ARC への移行の公開ノート


自動参照カウント(ARC)は、Objective-C のオブジェクトの自動メモリ管理を提供するコンパイラの機能です。解放と保持の操作を考えることよりも、ARC は興味深いコード、オブジェクトグラフ、およびアプリケーション内のオブジェクト間の関係に集中することができます。


ARC_Illustration

要約


ARC は、オブジェクトが必要な限り生きていますが、そうでない場合、保証しないため、コンパイル時にコードを追加することで機能します。概念的には、それは適切なメモリ管理を追加することで (高度なメモリ管理プログラミングガイド を参照)、手動参照カウントと同じメモリ管理規則に従います。


コンパイラが正しいコードを生成するために、ARC は、使用できるメソッドを制限し、自由通話ブリッジングを使用する方法(「自由通話ブリッジタイプ」を参照してください)を制限します。ARC は、またオブジェクト参照と 宣言されたプロパティ の、生涯に亘り資格を満たす物を導入します。


ARC は OS X 10.6 および v10.7(64 ビット·アプリケーション) と iOS 4 と iOS 5 で Xcode 4.2 上でサポートされています。弱い参照は、OS X 10.6 と iOS 4 ではサポートされません。


Xcode は(保持と、解放の呼び出しの削除など)の ARC 変換の機械的な部分を自動化し、( [編集]> [リファクタリング]>[Objective-C の ARC に変換]を選択します)移行ツールが自動的に処理できない問題を修正するのに役立つツールを提供しています。移行ツールは、ARC を使用するには、プロジェクト内のすべてのファイルを変換します。また、いくつかのファイルのマニュアル参照カウントを使用するのがより便利であればファイル単位で ARC を使用するように選択ができます。


以下も参照の事:


  • 高度なメモリ管理プログラミングガイド
  • Core Foundationのためのメモリ管理プログラミングガイド

  • ARCの概要


    保持(retain)解除(release)自動解放(autorelease) を使用する際に覚えておく代わりに、ARCは、オブジェクトの有効期間の要件を評価し、自動的に適切なメモリ管理を、コンパイル時に挿入します。コンパイラは、また適切な dealloc メソッドを生成します。通常、ARC だけを使用している場合は、手動の参照カウントを使用するコードと相互運用する必要がある場合にのみ一、伝統的なココアの命名規則が重要です。


    Person クラスの完全かつ正確な実装は次のようになります。


    @interface Person : NSObject
    @property NSString *firstName;
    @property NSString *lastName;
    @property NSNumber *yearOfBirth;
    @property Person *spouse;
    @end
     
    @implementation Person
    @end
    

    (オブジェクトのプロパティは、デフォルトでは強い(strong)です。強い属性は、ARC は新しい、生涯に亘り資格を満たす物を導入 で説明します)


    ARC を使用して、このような不自然なメソッドを実装できます。


    - (void)contrived {
        Person *aPerson = [[Person alloc] init];
        [aPerson setFirstName:@"William"];
        [aPerson setLastName:@"Dudney"];
        [aPerson setYearOfBirth:[[NSNumber alloc] initWithInteger:2011]];
        NSLog(@"aPerson: %@", aPerson);
    }
    

    PersonNSNumber オブジェクトのいずれもがリークしないように、ARC が、メモリ管理を処理します。

    また、PersontakeLastNameFrom: メソッドを以下の様に安全に実装することができます。


    - (void)takeLastNameFrom:(Person *)person {
        NSString *oldLastname = [self lastName];
        [self setLastName:[person lastName]];
        NSLog(@"Lastname changed from %@ to %@", oldLastname, [self lastName]);
    }
    

    ARC は oldLastName がの NSLog 文の前に解放されないことを保証します。


    ARC は新ルールを強要


    動く為に、ARC は、他のコンパイラモードを使用するときには存在しないいくつかの新しいルールを課している。ルールは、完全に信頼性のあるメモリ管理モデルを提供することを意図している。いくつかの場合には、それらは単に、最良の実行を課する他に、それらはコードを簡略化したり、メモリ管理に対処する必要がないのは明らかな結論です。これらのルールに違反した場合は、実行時に明らかになることがある微妙なバグではなく、すぐにコンパイル時エラーになります。


  • 明示的に dealloc を呼び出したり、retain、release、retainCount、または autorelease を実装したり、呼び出すことはできません。

  • 禁止は、@selector(retain)、@selector(release) の使用などに拡張します。


    インスタンス変数を解放する以外にリソースを管理するための必要がある場合は、dealloc メソッドを実装することができる。インスタンス変数を解放する必要はありませんが、(確かにすることはできません)システムクラスと ARC を使用してコンパイルされていない他のコードでは、[systemClassInstance setDelegate:nil] を起動する必要があります。


    ARC のカスタムの dealloc メソッドの呼び出しは、[supert dealloc](それは実際にはコンパイルエラーとなる)を必要としません。super への連鎖は、コンパイラによって自動化され、実施されます。


    まだ(通信自由ブリッジの管理を参照)CFRetain、CFRelease、およびコア・ファンデーション・スタイル・オブジェクトと関連した他の機能を使用することができます。


  • NSAllocateObject または NSDeallocateObject を使用することはできません。
  • alloc を使用してオブジェクトを作成します。ランタイムは、オブジェクトの割り当てを解除してくれます。


  • C の構造体のオブジェクトのポインタを使用することはできません。
  • struct を使用するのではなく、その代わりに、データを管理するために、Objective-C のクラスを作成することができます。


  • idvoid * の間には、偶然のキャストはありません。
  • オブジェクトの有効期間についてコンパイラに伝える特別なキャストを使用しなければなりません。Objective-C のオブジェクトと、関数の引数として渡す Core Foundation の型の間でキャストするためにこれを行う必要があります。詳細については、通信自由ブリッジの管理を参照してください。


  • NSAutoreleasePool オブジェクトを使用することはできません。

  • ARC は、代わりに @autoreleasepool ブロックを提供します。これらは、NSAutoreleasePool よりも効率的であるという利点があります。

  • メモリゾーンを使用することはできません。
  • これ以上 NSZone を使用する必要はありません-それらは現代の Objective-C ランタイムによってとにかく無視されます。


    手動の保持・解除コードとの相互運用を可能にするために、ARC はメソッドの名前付けに制約を課しています:


  • アクセサは、new で始まる名前を付けることはできません。これは逆に言うと、例えば、別のゲッターを指定しない限り、new で始まる名前のプロパティを宣言することができないことを意味します。

  • // Won't work:
    @property NSString *newTitle;
     
    // Works:
    @property (getter=theNewTitle) NSString *newTitle;
    


    ARC は新しい、生涯に亘り資格を満たす物を導入


    ARC は、オブジェクトのいくつかの新しい生涯に亘り資格を満たす物を導入、弱参照を導入しています。弱い参照は、それが指すオブジェクトの有効期間を延長せず、オブジェクトへの強い参照がない場合に自動的に nil にはなりません。


    プログラムでオブジェクトグラフを管理するために、これらの資格を満たすものを利用して下さい。具体的には、ARC は(循環保持として以前知られていた- 実践メモリ管理 を参照) 強い循環参照 を防げません。弱い関係を適切に使用すれば、循環参照を作成しないのに役立ちます。


    プロパティの属性


    以下の例に示すように weakstrong のキーワードは、宣言された新しいプロパティ属性として導入されます。


    // The following declaration is a synonym for: @property(retain) MyClass *myObject;
    @property(strong) MyClass *myObject;
     
    // The following declaration is similar to "@property(assign) MyClass *myObject;"
    // except that if the MyClass instance is deallocated,
    // the property value is set to nil instead of remaining as a dangling pointer.
    @property(weak) MyClass *myObject;
    

    ARC の下で、strong がオブジェクト型のデフォルトです。


    変数の資格を満たすもの


    const に代わり、変数に対する、次の生涯に亘り資格を満たすものを使用して下さい。


    __strong
    __weak
    __unsafe_unretained
    __autoreleasing
    

  • __strong がデフォルトです。オブジェクトは、それへの強いポインタが存在する限り、「生きている」ままです。
  • __weak は生きて参照されたオブジェクトを保持しない参照を指定します。オブジェクトへの強い参照がない場合、弱い参照は nil に設定されます。
  • __unsafe_unretained は生きて参照されたオブジェクトを保持しない参照を指定し、オブジェクトへの強い参照が存在しない場合は nil に設定されません。それが参照するオブジェクトが割り当て解除された場合、ポインタはぶら下がったままです。
  • __autoreleasing は、参照(id *)で渡され、復帰時に自動解放される引数を表すために使用されます。
  • 正しく変数を飾る必要があります。オブジェクト変数の宣言に修飾子を使用する場合は、正しい形式は次のとおりです:


    ClassName * qualifier variableName;
    

    例えば:


    MyClass * __weak myWeakReference;
    MyClass * __unsafe_unretained myUnsafeReference;
    

    他の変異体は、技術的には間違っていますが、コンパイラに「許され」ます。問題を理解するには、http://cdecl.org/ を参照してください。

    スタック上で __weak 変数を使用する際は注意してください。次の例は動きます:


    NSError *error;
    BOOL OK = [myObject performOperationWithError:&error];
    if (!OK) {
        // Report the error.
        // ...
    

    ただし、エラー宣言は暗黙的です。


    NSError * __strong e;

    そして、メソッドの宣言は、一般的に次のようになります:


    -(BOOL)performOperationWithError:(NSError * __autoreleasing *)error;

    コンパイラは、そのためコードをこのように書き換えます:


    NSError * __strong error;
    NSError * __autoreleasing tmp = error;
    BOOL OK = [myObject performOperationWithError:&tmp];
    error = tmp;
    if (!OK) {
        // Report the error.
        // ...
    

    ローカル変数宣言(__strong) とパラメータ(__autoreleasing) の間のミスマッチで、一時的な変数を作成するようにコンパイラーにさせます。パラメータ id__strong * を宣言することで__strong 変数のアドレスを取るとき、元のポインタを得られます。別の方法としては、__autoreleasing として変数を宣言することができます。


    強い循環参照を回避するために生涯に亘り資格を満たすものを使用


    強力な循環参照を避けるために、生涯に亘り資格を満たすものを使用することができます。例えば、親子階層と親がその子どもへの参照が必要な時とその逆が配置されたオブジェクトのグラフがある場合は、親から子への関係を強く、また子から親への関係を弱く作って下さい。他の状況では、それらは ブロックオブジェクト を伴う場合は特に、より微妙な場合があります。


    マニュアル参照カウントモードでは、__block id x; は x を保持する効果はありません。ARC モードでは、__block id x; は(ちょうど他のすべての値のように)x を保持するのがデフォルトです。 ARC の下にマニュアル参照カウントモードの動作を得るには、__unsafe_unretained __block id x; を使用することができます。__unsafe_unretained は、名前が示すように(それがぶら下がるる可能性があるため)、非保持変数を持つことは危険ですので、お勧めしません。二つの、より良いオプションは、保持悪循環を断ち切るために(iOS 4 または OS X10.6 をサポートする必要がない場合)__weak を使用するか、nil__block 値に設定するかです。


    次のコード断片は、場合によっては、手動参照カウントで使用されるパターンを使用して、この問題を示しています。


    MyViewController *myController = [[MyViewController alloc] init…];
    // ...
    myController.completionHandler =  ^(NSInteger result) {
       [myController dismissViewControllerAnimated:YES completion:nil];
    };
    [self presentViewController:myController animated:YES completion:^{
       [myController release];
    }];
    

    上述したように、代わりに、__block 修飾子を使用し、nil を完了ハンドラの myController 変数に設定します。


    MyViewController * __block myController = [[MyViewController alloc] init…];
    // ...
    myController.completionHandler =  ^(NSInteger result) {
        [myController dismissViewControllerAnimated:YES completion:nil];
        myController = nil;
    };
    

    別の方法として、一時的に、__weak 変数を使用することができます。次の例は、簡単な実装を示しています。


    MyViewController *myController = [[MyViewController alloc] init…];
    // ...
    MyViewController * __weak weakMyViewController = myController;
    myController.completionHandler =  ^(NSInteger result) {
        [weakMyViewController dismissViewControllerAnimated:YES completion:nil];
    };
    

    しかしながら、平凡でないサイクルでは、以下のように:


    MyViewController *myController = [[MyViewController alloc] init…];
    // ...
    MyViewController * __weak weakMyController = myController;
    myController.completionHandler =  ^(NSInteger result) {
        MyViewController *strongMyController = weakMyController;
        if (strongMyController) {
            // ...
            [strongMyController dismissViewControllerAnimated:YES completion:nil];
            // ...
        }
        else {
            // Probably nothing...
        }
    };
    

    クラスが __weak と互換性がない場合、いくつかのケースでは、__ unsafe_unretained を使用することができます。それは、__ unsafe_unretained ポインタはまだ有効で、まだ問題になっている同じオブジェクトを指していることを検証するのは難しい、あるいは不可能であることがありうるので、これは、重要なサイクルのための非現実的になることがあります。


    ARC は、自動解放プールを管理するための新しい宣言を使用


    ARC を使用すると、直接 NSAutoreleasePool クラスを使用して自動解放プールを管理することはできません。代わりに、@autoreleasepool ブロックを使用します。


    @autoreleasepool {
         // Code, such as a loop that creates a large number of temporary objects.
    }
    

    この単純な構造で、コンパイラが参照カウントの状態について推論することができます。エントリーでは、自動解放プールがプッシュされます。正常終了時(ブレーク、リターン、goto、fall-through など)、自動解放プールはポップされます。出口は例外が原因であれば、既存のコードとの互換性を確保するため、自動解放プールはポップされません。


    この構文は、すべての Objective-C モードで使用可能です。これは、NSAutoreleasePool クラスを使用するよりも効率的です。したがって、NSAutoreleasePool を使用する代わりにそれを採用することをお勧めします。


    アウトレットを管理するパターンはプラットフォーム間で一貫する


    iOS と OS X で アウトレット を宣言するパターンは、ARC で変化し、両方のプラットフォームで一貫したものとなりました。一般的に 採用すべきパターンは、次のとおりです:アウトレットは weak であるべきで、nib ファイル内のトップレベルのオブジェクト(またはストーリーボードシーン) へのファイルの所有者からのものは strong であるべきだが、それを除けば。


    完全な詳細は、リソース·プログラミング·ガイドnib ファイル に記載されています。

    スタック変数は nil で初期化されます


    ARC を使用すると、strong、weak、および autoreleasing スタック変数は暗黙的に nil で初期化されます。たとえば、次のように:

    - (void)myMethod {
        NSString *name;
        NSLog(@"name: %@", name);
    }
    

    むしろ、おそらくクラッシュより name の値に null を入れ、ログに記録します。


    ARC を有効/無効にするコンパイラフラグを使用


    新しい -fobjc-arc コンパイラフラグを使用して、 ARC を有効にしてください。また、いくつかのファイルのマニュアル参照カウントの使用がより便利であればファイル単位で ARC を使用するように選択することができます。デフォルトのアプローチとして ARC を採用するプロジェクトでは、そのファイルの新しい -fno-objc-arc のコンパイラフラグを使用して特定のファイルで ARC を無効にすることができます。


    ARC は、Xcode 4.2 以降でサポートされ、OS X v10.6以降(64ビット·アプリケーション)と iOS 4 以降用とされています。弱い参照は、OS X v10.6 と iOS 4 ではサポートされていません。Xcode 4.1 以前のバージョンには ARC のサポートはありません。


    通信自由ブリッジの管理


    多くの Cocoa アプリケーションでは、コアグラフィックス(CGColorSpaceRefCGGradientRef のようなタイプを使えます)のようなコア・ファウンデーション代表を採用した(例えば CFArrayRefCFMutableDictionaryRef など)フレームワークから、あるいはコア・ファウンデーション・フレームワーク自体から、コア・ファウンデーションのスタイルのオブジェクトを使用する必要があります。


    コンパイラは自動的にはコア・ファウンデーションのオブジェクトの寿命を管理しません。コア・ファウンデーションのメモリ管理規則によって指示されるように(コア・ファウンデーションのためのメモリ管理プログラミングガイドを参照)CFRetainCFRelease(または対応するタイプ固有亜種)を呼び出す必要があります。


    Objective-C とコア・ファウンデーションのスタイルのオブジェクト間でキャストする場合は、(ObjC/runtime.h で定義されている)キャストや、コア・ファウンデーションのスタイルのマクロ(NSObject.h で定義されている)いずれかを使用してオブジェクトの所有権の意味について、コンパイラに指示する必要があります。


  • __bridge は、 Objective-C と コア・ファウンデーション間で所有権の移転なしにポインタを移します。
  • __bridge_retained または CFBridgingRetain は、コア・ファウンデーションのポインタに Object-C のポインタをキャストし、また所有権をあなたに移します。
  • あなたは、オブジェクトの所有権を放棄する CFRelease または関連した関数を呼出す責任があります。

  • __bridge_transfer または CFBridgingRelease は、非 Object-C ポインタを Object-C に移動し、所有権を ARC に移します。
  • ARC は、オブジェクトの所有権を放棄する責任があります。


    たとえば、次のようなコードがあった場合:


    - (void)logFirstNameOfPerson:(ABRecordRef)person {
     
        NSString *name = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
        NSLog(@"Person's first name: %@", name);
        [name release];
    }
    

    これを以下のように置き換えます:


    - (void)logFirstNameOfPerson:(ABRecordRef)person {
     
        NSString *name = (NSString *)CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
        NSLog(@"Person's first name: %@", name);
    }
    

    コンパイラは、ココアメソッドから返される CF オブジェクトを扱う


    コンパイラは、コア・ファウンデーションの型は、歴史的な Cocoa の命名規則(アドバンストメモリ管理プログラミングガイドを参照してください)に従う Objective-C のメソッドを理解します。例えば、コンパイラは、iOS では、UIColor のメソッド CGColor で返される CGColor は、所有されていません。まだ、以下の例で示すように、適切なタイプキャストを使用しなければなりません。


    NSMutableArray *colors = [NSMutableArray arrayWithObject:(id)[[UIColor darkGrayColor] CGColor]];
    [colors addObject:(id)[[UIColor lightGrayColor] CGColor]];
    

    所有権のキーワードを用いてキャストファンクションのパラメータ


    関数呼び出しで Objective-C とコア・ファウンデーションのオブジェクト間のキャストするときには、渡されたオブジェクトの所有権の意味についてコンパイラに指示する必要があります。コア・ファウンデーションのオブジェクトの所有権の規則は(コア・ファウンデーションのためのメモリ管理プログラミングガイドを参照)コア・ファウンデーションのメモリ管理規則で指定されたものです。 Objective-C のオブジェクトのための規則は、高度なメモリ管理プログラミングガイドで指定されています。


    以下のコードの断片では、配列は CGGradientCreateWithColors 関数に渡され、適切なキャストが必要です。arrayWithObjects: によって返されるオブジェクトの所有権は、関数に渡されておらず、以下のようにキャストは __bridge です。


    NSArray *colors = <#An array of colors#>
    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors,
     locations);
    

    コードの断片は、次のメソッド実装文脈で示されている。コア・ファウンデーションのメモリ管理規則によって決定される、コア・ファウンデーションのメモリー管理関数を使用する事を注意されたい。


    - (void)drawRect:(CGRect)rect {
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
        CGFloat locations[2] = {0.0, 1.0};
        NSMutableArray *colors = [NSMutableArray arrayWithObject:(id)[[UIColor darkGrayColor] CGColor]];
        [colors addObject:(id)[[UIColor lightGrayColor] CGColor]];
        CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);
        CGColorSpaceRelease(colorSpace);  // Release owned Core Foundation object.
        CGPoint startPoint = CGPointMake(0.0, 0.0);
        CGPoint endPoint = CGPointMake(CGRectGetMaxX(self.bounds), CGRectGetMaxY(self.bounds));
        CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint,
                                    kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
        CGGradientRelease(gradient);  // Release owned Core Foundation object.
    }
    

    プロジェクトの変換での一般的な問題


    既存のプロジェクトを移行するときには、様々な問題に遭遇する可能性があります。ここで一緒に、いくつかの一般的な問題と、解決策を示します。


    よくある質問


    どのよう ARC を考えたらいいですか?どこに retain/release を置くのですか?

    retain/release 呼び出しをどこに置いたらいいか考えるのはよして、代わりに、アプリケーションのアルゴリズムを考えて下さい。オブジェクトの「強弱」ポインタについて、オブジェクトの所有権、および可能な保持のサイクルについて考えて下さい。


    まだオブジェクトのための dealloc メソッドを記述する必要がありますか?

    多分

    コア・ファウンデーションのオブジェクト、ファイル記述子など、それらのリソースを ARC は dealloc メソッドを記述することによって寿命の管理や malloc/free、の自動化していないためです。

    (実際にはできない)インスタンス変数を解放する必要はありませんが、システム·クラスと ARC を使用してコンパイルされていない他のコードでは[self setDelegate:nil] を起動する必要があります。


    ARC では dealloc メソッドは[super dealloc] を呼出す必要もなく、許されてもいません。super への連鎖は、実行時に処理され、実施されている。


    ARC では、rtain のサイクルはまだ可能ですか?

    はい。

    ARC は retain/release を自動化し、retain サイクルの問題を継承します。幸いなことに、プロパティが retain しているかどうかをすでに宣言しているため、ARC に移行したコードはまれにしかメモリーリークしません。


    ARC ではブロックはどのように働きますか?

    リターンの時のように ARC モードのスタックを、ブロックを渡すときのようにブロックは"仕事をよくこなす"。これ以上ブロックコピーを呼び出す必要はありません。まだ arrayWithObjects: にスタックを「ダウン」するときに、[^{} copy] を使用する必要がありますし、他のメソッドが retain します。


    注意すべきことの一つは、NSString * __block myString は、ARC モードでは retain され、ぶら下がりポインタではないことです。以前の動作を取得するには、__block NSString * __unsafe_unretained myString か(もっとよくは)__block NSString * __weak myString

    を使用します。


    スノーレパードを使用して ARC と OS X 用のアプリケーションを開発できますか?


    いいえ。それは 10.7 の SDK が含まれていないので、Xcode 4.2 のスノーレパードのバージョンは、まったく OS X 上で ARC をサポートしていません。スノーレパードのための Xcode 4.2 は、しかし iOS 用の ARC をサポートして、ライオンのための Xcode 4.2 は、OS X と iOS の両方をサポートしています。これは、スノーレパードの上で動作する ARC アプリケーションをビルドするためにライオンのシステムが必要な事を意味します。


    ARC の下で retain されたポインタの C 配列を作れますか?

    はい、以下の例で示すように、できます:


    // Note calloc() to get zero-filled memory.
    __strong SomeClass **dynamicArray = (__strong SomeClass **)calloc(entries, sizeof(SomeClass *));
    for (int i = 0; i < entries; i++) {
         dynamicArray[i] = [[SomeClass alloc] init];
    }
     
    // When you're done, set each entry to nil to tell ARC to release the object.
    for (int i = 0; i < entries; i++) {
         dynamicArray[i] = nil;
    }
    free(dynamicArray);
    

    注意すべき点がいくつかあります。

  • デフォルトでは __autoreleasing SomeClass ** のため、いくつかの場合、__strong SomeClass ** と記述する必要があります。
  • 割り当てられたメモリは、ゼロで埋めなければなりません。
  • 配列を(memsetbzero が動作しません)解放する前に各要素を nil に設定する必要があります。
  • memcpy や、realloc を避ける必要があります。

  • ARC は遅いですか?

    それはあなたが何を測定しているかに依存しますが、一般的に「いいえ」です。コンパイラが効率的に多くの余分な retain/release コールを取り除き、一般的に Objective-C 実行時の速度向上に多くの努力がつぎ込まれて来ました。具体的には、一般的な「retain/autorelease オブジェクトを返す」パターンもはるかに高速で、メソッドの呼び出し元が ARC コードの場合に、実際に自動解放プールの中にオブジェクトを置きません。


    注意すべき一つの問題は、最適化が、共通のデバッグ構成で実行されず、その多くは、-Os より -O0 で、retain/release のトラフィックを見ることでしょう。


    ARC は ObjC++ モードで動作しますか?

    はい。クラスやコンテナに strong/weak の id を入れることができます。ARC コンパイラは、この作業を完成させるためにコンストラクタやデストラクタをコピーし、retain/release ロジックを合成する。


    どのクラスが弱い参照をサポートしていないですか?

    現在、以下のクラスのインスタンスへの弱い参照を作成することはできません。

    NSATSTypesetter、NSColorSpace、NSFont、NSMenuView、NSParagraphStyle、NSSimpleHorizontalTypesetter, そしてNTTextViewer.


    注意:また、OS X v10.7 では、NSFontManager、NSFontPanel、NSImage、NSTableCellView、NSViewController、NSWindow、 そして NSWindowController のインスタンスへ弱い参照を作成はできません。また、OS X v10.7 内では AV Foundation のフレームワークは全てのクラスは弱い参照をサポートしません。


    宣言されたプロパティの場合は、weak の代わりに assign を使用する必要があります。変数に対しては、__weak の代わりに__unsafe_unretained を使用する必要があります。


    さらに、ARC の下 NSHashTable、NSMapTable、 または NSPointerArray のインスタンスから弱い参照を作成することはできません。


    NSCell や NSCopyObject を使用する別のクラスをサブクラス化する際に何をしなければならないのですか?

    特別な事は何もない。ARC は、以前に明示的に保持を追加する必要があった例の面倒を見ます。ARC では、すべてのコピーメソッドは、単にインスタンス変数をコピーします。

    特定のファイルでは ARC から手を引くことはできますか?

    はい。

    ARC を使用するようにプロジェクトを移行する場合、-fobjc-arc のコンパイラフラグは、Objective-C のソースファイルに全てデフォルトとして設定されています。そのクラスに -fno-objc-arc のコンパイラフラグを使用して、特定のクラスで ARC を無効にすることができます。Xcode で、[ターゲットビルドフェーズ]タブで、ソースファイルのリストを表示するために[ソースグループをコンパイル]を開きます。フラグを設定したいファイルをダブルクリックし、ポップアップ·パネルで -fno-objc-arc を入力し、[完了]をクリックします。


    fno-objc-arc



    GC(ガベージコレクション)は、Mac 上では旧式となったのですか?

    ガベージコレクションは、OS X マウンテンライオンの v10.8 で廃止され、かつ OS Xの将来のバージョンでは削除される予定です。自動参照カウントは、推奨される代替技術です。既存のアプリケーションの移行を支援するために、Xcode 4.3 以降の ARC 移行ツールは、ガベージコレクションを使った OS X アプリケーションを ARC に移行するのをサポートします。


    注意:Mac App Store を対象としたアプリのために、Apple は Mac App Store のガイドラインは旧式の技術の使用を禁止する(Mac アプリ用の App Store レビューガイドラインを参照) ので、できるだけ実現可能な限り早く、ARC でガベージコレクションを置き換えることを強くお勧めします。







    目次
    Xcode 9 の新機能

  • ARC への移行の公開ノート
  • 要約
  • ARCの概要
  • ARC は新ルールを強要
  • ARC は新しい、生涯に亘り資格を満たす物を導入
  • プロパティの属性
    変数の資格を満たすもの
    強い循環参照を回避するために生涯に亘り資格を満たすものを使用
    ARC は、自動解放プールを管理するための新しい宣言を使用
    スタック変数は nil で初期化されます
    アウトレットを管理するパターンはプラットフォーム間で一貫する
    スタック変数は nil で初期化されます
    ARC を有効/無効にするコンパイラフラグを使用
  • 通信自由ブリッジの管理
  • コンパイラは、ココアメソッドから返される CF オブジェクトを扱う
    所有権のキーワードを用いてキャストファンクションのパラメータ
    プロジェクトの変換での一般的な問題
    よくある質問












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ