4

ARC と copyに関するCraig Hockenberryの短いブログ記事を読んだところです。私が今持っている質問は、インスタンス変数に割り当てられたイニシャライザに渡されるパラメータは常に使用するべきですか? それともインスタンス変数の型に依存するのでしょうか?copy

#import "MyObject.h"

@implementation MyObject {
    SomeType *_ivar1;
    SomeOtherType *_ivar2;
}

-(id)initWithParam1:(SomeType *)param1 andParam2:(SomeOtherType *)param2
{
    if ((self == [super init])) {
        _ivar1 = [param1 copy]; // Always good
        _ivar2 = [param2 copy]; // practice?
    }

    return self;
}

@end
4

2 に答える 2

4

この投稿を理解するための鍵は、次のステートメントにあると思います。

-init 中にアクセサーを使用するのは悪い考えだと思うので、によって定義されたコピー セマンティクス@propertyは使用されず、ARC は参照をコピーする代わりに喜んで保持します。

Craig は次のケースについて具体的に話していると思います。

@interface MyObject : NSObject {
    SomeType *_ivar1;
}
-(id)initWithParam1:(SomeType *)param1;
@property (copy, nonatomic) SomeType* prop1;
@end

@implementation MyObject
@synthesize prop1 = _ivar1;
-(id)initWithParam1:(SomeType *)param1 {
    if ((self == [super init])) {
        /*
        Craig could have called

        self.prop1 = param1;

        but he believes that it's a bad idea to call accessors
        from the initializer, so he calls copy explicitly.
        */
        _ivar1 = [param1 copy];
    }
    return self;
}
@end
于 2012-07-06T18:52:38.943 に答える
2

変数のタイプとインテントによって異なります。

単純な型 (NSString、NSArray、NSNumber など) の場合は、通常、格納された型を不変にする必要があるため、コピーを使用します。firstNameつまり、 のインスタンスを渡すことによって外部から変更できるプロパティを持つことは意味がありませんNSMutableString

より複雑なクラス (状態と機能の両方をカプセル化するクラス) の場合、状態が時間の経過とともに変化する可能性があるため、通常は正確にコピーする必要はありません。たとえば、アプリが、StreamingVideo インスタンスにカプセル化されたビデオを再生する VideoPlayer インスタンスを持つストリーミング ビデオ アプリである場合、StreamingVideo をコピーする必要はありません。これは、より多くのデータがダウンロードされるにつれて、その内部状態が常に変化するためです。 (またはエラーが発生します)。

つまりcopy、状態の不変のスナップショットが必要な場合に使用され、参照は、B の状態を変更/監視/クエリする目的でオブジェクト A を B に接続する場合に使用されます。

そして、はい、あなたはそれが一貫していることを望んでいます。プロパティがcopyあり、そのプロパティを設定する便利な初期化子がある場合は、便利な初期化子もプロパティに設定されているものをすべてコピーするようにしてください。

于 2012-07-06T20:22:49.177 に答える