NSMutableArrayなどの可変オブジェクトでObj-C 2.0プロパティを使用する最良の方法は何ですか?
-
03-07-2019 - |
質問
NSMutableArrayプロパティを持つObj-C 2.0クラスがあります。次のコードを使用すると、合成されたセッターは変更可能なコピーではなく、不変のコピーを提供します。
@property (readwrite, copy) NSMutableArray *myArray;
Appleが次の構文を実装しなかった理由はありますか?
@property (readwrite, mutablecopy) NSMutableArray *myArray;
mutablecopy
がないため、この(一見一般的な)状況を処理する最良の方法は何ですか? -mutableCopyを実行する独自のセッターを作成する必要がありますか?
解決
前述のように、それを行うための正しい方法は、可変配列をプロパティにすることではありません。 KVCに準拠するために何を実装する必要があるかについての優れた説明がありますこちら。
他のヒント
先ほど同じ問題に遭遇し、 Apple Developer Connectionのドキュメントでは、セッターの独自の実装を提供することを推奨しています。リンクされたドキュメントのコードサンプル:
@interface MyClass : NSObject {
NSMutableArray *myArray;
}
@property (nonatomic, copy) NSMutableArray *myArray;
@end
@implementation MyClass
@synthesize myArray;
- (void)setMyArray:(NSMutableArray *)newArray {
if (myArray != newArray) {
[myArray release];
myArray = [newArray mutableCopy];
}
}
Cocoaで NSMutableArray
を渡すことは一般的ではありません。標準のCocoaプラクティスは、キー値コーディングに準拠したメソッド。これには2つの利点があります:
- キー値の監視は期待どおりに機能します(NSMutableArrayを監視すると、あなたが望んでいない動作につながるいくつかのケースがあります)
- データ構造自体ではなく、変更メソッド(例:
-[MyObject insertObjectInMyProperty:(id)newObject atIndex:(NSUInteger)i]
)を公開しているため、データ構造の実装は隠されています。
可変配列を渡すことは、Cocoaでは一般的な慣行ではないことに注意してください。プライベートな可変配列を内部ストレージとして使用できますが、プレーンなNSArrayオブジェクトを使用してオブジェクトを追加または取得するメソッドを作成します。これが、mutablecopyプロパティの宣言がない理由かもしれません。
独自のセッターを作成する必要があります。
NSMutableArrayを保持する正しい方法は、retainプロパティを使用することです:
@property (nonatomic, retain) NSMutableArray *myArray;
独自のセッターを作成したり、コピーを使用する必要はありません。 copyプロパティは、プロパティが別のオブジェクトにキャプチャされるときに実際にコピーする必要があるNSArrayで使用する必要があります。たとえば、NSMutableArrayオブジェクトをcopyプロパティを持つNSArray型のプロパティに割り当てる場合、可変配列のコピーを" capture"に作成します。それ以降の不変のプロパティとして。
そして、Marcには正しいアプローチがあります。通常、NSMutableArrayをオブジェクトのパブリックAPIの一部にすることはありません。パブリックプロパティがある場合は、copyプロパティを持つNSArrayにすることができます。