6

この質問に対する正しい答えを得ることができませんでした。重複が見つかった場合は、正しい参照リンクで複製してください。

知りたかったのは、参照カウントがインクリメントされる方法です。alloc/init と keep は参照カウントを増やしますが、'copy' も参照カウントを '1' に増やしますか?

ありがとう。

4

1 に答える 1

10

copyメソッド名が示すように、レシーバーのカーボンコピーである新しいオブジェクトを作成します(実際には、copy各クラスのメソッドの実装に依存しますが、とにかくそれがメソッドの目的です)。

したがって、実際には「の参照カウントを 1 増やす」のではなく、新しく割り当てられたオブジェクトとして refcount が 1 の新しいオブジェクトを作成し、元のオブジェクトと同じプロパティ / ivar 値を持つようにします。

したがってPerson、プロパティnamesurnameおよびを持つクラスがあると想像してください。メソッドを自分でage実装する必要がある場合は、次のようになります。copy

-(id)copy
{
    // Create a new instance
    Person* mycopy = [[Person alloc] init];
    // Make it an exact copy of the original
    mycopy.name = self.name;
    mycopy.surname = self.surname;
    mycopy.age = self.age;
    // and return that copy
    return mycopy;
}

この場合、後でコピーを変更しても、オリジナルは変更されないことに注意してください。これは、別のインスタンスであるためです。

この原則では、元のオブジェクトの refcount は 1 ずつインクリメントされませんが、refcount が 1 の新しいオブジェクトがあり (この新しいオブジェクトを自分で作成するために alloc/init を実行したかのように)、依然として解放または自動解放する必要があります。ある時点で自分で (ARC を使用していない場合)。そのため、オブジェクトの呼び出しは、呼び出しの必要性とcopy同じ規則に従うretainか、ある時点で参照カウントのバランスをとる必要があるためです。allocreleaseautorelease


いくつかの例外/特殊なケースがあることに注意してNSArrayくださいNSString. このような場合、オリジナルのクローンであるコピー (別のオブジェクト インスタンス) を作成することは合理的ですが、オリジナルは変更できず、実際には効率的ではなく、最適化できます。

したがって、およびその他のような場合NSArrayNSStringこれらは本質的に不変のクラスであるため、元の(コピーも)変更できないため、動作は同じであるため、copyメソッドは単純に実装されるだけです。retain

もちろん、 (たとえばからmutableCopyを取得するための) の実装は単純な保持ではなく実際のコピーを行い、変更可能なサブクラスでのメソッドの実装も同様に実際のコピーを行いますが、不変オブジェクトの不変コピーの場合、別のインスタンスを割り当てるポイントは、一般に役に立たず、メモリを消費するため、 と同じように実装されます。NSMutableArrayNSArraycopyNSMutableStringNSMutableArrayretain

ただし、この最適化の可能性はすべて、動作 (クラスは不変であるため) もメモリ管理ポリシーも変更されません (releaseによって返されるオブジェクトが必要なためcopy) 。

于 2012-10-10T09:42:07.910 に答える