2

次の例ではstringWithString:(NSString *)、のメモリアドレス/場所をコピーしますtheNamename、それとも実際にデータをからにコピーしtheNameますnameか?

@interface AddressCard:NSObject
-(void)setName:(NSString *)theName;
@end

@implementation AddressCard
NSString *name;
-(void)setName:(NSString *)theName
{
    if(name!=theName)
    name = [NSString stringWithString:theName];
}
@end

コードを次のように変更した場合、何がcopy変わりますか?

@interface AddressCard:NSObject
@property (copy, nonatomic) NSString *name;
@end

@implementation AddressCard
@synthesize name;
@end

一般に、copy@property属性)はデータのアドレスをコピーしますか、それともある変数から別の変数にデータをコピーしますか?後者の場合、変数が大きなデータを表すときに多くのメモリを消費していませんか?

お手数をおかけしますが、よろしくお願いいたします。

4

2 に答える 2

2

stringWithStringは、変更可能である場合にコピーを作成します。ただし、自動リリースされるalloc、init、copyメソッドではないことに注意してください。現在保持しているコピーは、そのsetメソッドが終了した直後のある時点でプーフになります。代わりにinitWithStringを実行すると、別の文字列も作成されますが、保持されます。

copy属性は、渡されたオブジェクトにコピーメッセージを送信した後に返されるオブジェクトがプロパティに割り当てられることを意味します。つまり、コピーの処理方法を決定するのはそのオブジェクトタイプ次第です。特定の文字列の例では、(copy)は、文字列のコピーを作成して呼び出し元に戻します。このコピーは保持されます。保持されたオブジェクトを解放するのは呼び出し元の責任です。メモリガイドラインに従って、コピーはオブジェクトを保持します。

于 2012-08-25T13:36:25.817 に答える
2

+[NSString stringWithString:]文字列を効果的に「コピー」します。

一般に、copy(@property attribute)はデータのアドレスをコピーしますか、それともある変数から別の変数にデータをコピーしますか?

オブジェクトがと見なすものは何でも実行しますcopy。新しいオブジェクトを返す場合もあれば、自分自身を返す場合もあります。たとえば+[NSString stringWithString:]、パラメータがすでに不変である場合は、保持され自動解放されたパラメータを返すことができます。パラメータが可変の場合、新しいインスタンスが返されるため、不変のインスタンスが保証されます。

後者の場合、変数が大きなデータを表すときに多くのメモリを消費していませんか?

ああ-でもそれがコツだ!はい、コピーを使用して多くの新しい割り当てを行うことになる可能性がありますが、多くの場合、不変型を優先してを使用すると、参照カウントオブジェクトのコピーが本当に非常に浅くなるというトリックがありますcopy。多くのコレクションタイプは、すでに不変である場合、またはそれらのivarがそうする可能性がある場合、単純に自分自身を返すことができます。したがって、実際には、可変オブジェクトを渡さないようにすることをお勧めします。したがって、不変コピーを早期に作成すると、この最適化を伝播できます。 、そして大量の割り当てを節約します(ただし、常にではありません-これらすべてのバリアントには多くのコーナーケースがあります)。

注:すべてのクラスが不変性と可変性を区別するわけではないため、コピーが常に不変オブジェクトを返すとは限りません。

于 2012-08-25T13:44:47.773 に答える