2

抽象的な方法で、次のことをしたいと思います。

// .h
@interface SomeObject : NSObject
@property (readonly) NSArray myProperty;
@end

// .m
@interface SomeObject ()
@property (readwrite) NSMutableArray myProperty;
@end

@implementation SomeObject
@end

セクションSubclassing with Properties in the Mac Developer Libraryreadonlyによると、プロパティを で上書きすることが許可されていますreadwrite。機能しないのは、プロパティ タイプのサブクラスを使用することです。例として NSMutableArray を使用しましたが、他のクラス/サブクラスの組み合わせでもかまいません。

継承ルールによると、それでも問題ないはずです。readonlyサブクラスオブジェクトを返すこともできるゲッターを生成するだけです。

内部使用のためにいくつかのプロパティのサブクラス型が必要な場合、そのようなケースにどのように対処しますか?

self.醜い方法は次のようになりますが、サブクラスのメソッドにアクセスするときにゲッターとセッターを使用できないことを意味するため、避けたいと思います。

// .h
@interface SomeObject : NSObject
@property (readonly) NSArray myProperty;
@end

// .m
@implementation SomeObject {
    NSMutableArray _myProperty;
}
@synthesize myProperty = _myProperty;
@end
4

2 に答える 2

4

編集(編集に基づく):編集後の特定のケースは、やや特殊で一般的なケース(同時に両方である場合)であり、慎重な検討が必要です。

これが特別な理由は、サブクラスが公開されたクラスの変更可能な形式であるためです。発信者は、受信後に変更されないことを期待する場合があります。しかし、内部オブジェクトを戻すと、変更される可能性があります。いくつかのオプションがあります:

  • 不変のコピーを返します。これは、多くの場合、小さなコレクションに最適なソリューションです。それは確かに最も単純です。ただし、アクセサーが頻繁に呼び出される可能性があり、コレクションが大きい場合は、非常に高価になる可能性があります。

  • 内部プロパティを不変にします。プロパティの変更よりもプロパティのリクエストの方がはるかに一般的である場合は、オブジェクトが変更されたときに ( などを使用して) オブジェクトを再作成する方が効率的arrayByAddingObject:ですsubarrayWithRange:

  • 返されるオブジェクトが変更される可能性があることを呼び出し元に警告します....うーん...パフォーマンスが必要な1つのケースでこれを行いましたが、非常に危険です。

  • 私は実際にこの方法で行ったことはありませんが、次の方法で独自のコピー オン ライトを作成することもできます。変更可能なバージョンを直接返し、現在は「ダーティ」であることを示すフラグをマークします。内部で変更が必要な場合は、変更可能なコピーを作成してプロパティに保存します (古いコレクションを手放します)。これは非常に複雑に思えますが、状況によっては、特に読み取りと書き込みが別々に集中する傾向がある場合 (多数の読み取りの後に多数の書き込みが続く場合) に役立つ可能性があります。


NSObject と NSString に基づく古い回答:

ここでのあなたの目標は、それが?myPropertyであるという事実を漏らすのではなく、不透明な型にすることだと思います。NSStringおそらく、実際にどのように実装されているかについて、後で考えを変えることができるのでしょうか? いくつかのオプションがあります。最も簡単なのは type の定義idです。次に、内部的には文字列として扱います。id何でもかまいません。通常は よりも優先されNSObject*ます。

内部でより多くの型安全性が必要な場合は、型の別の名前でプライベート プロパティを作成し、次のようNSStringに返すことができます。myProperty

SomeObject.h

@interface SomeObject : NSObject
@property (readonly) id myProperty;
@end

SomeObject.m

@interface SomeObject ()
@property (readwrite) NSString *myInternalProperty;
@end

@implementation SomeObject
- (id)myProperty {
  return myInternalProperty;
}
@end

使用できる別の隠蔽手法 (隠蔽が非常に重要な場合) は、サブクラスです。例えば:

SomeObject.h

@class MyOpaque;
@interface SomeObject : NSObject
@property (readonly) MyOpaque *myProperty;
@end

SomeObject.m

@interface MyOpaque : NSString
@end
@implementation MyOpaque
@end

@implementation SomeObject
@end

呼び出し元には の@interface定義MyOpaqueがないため、コンパイラの警告なしにメッセージを送信することはできません。

于 2012-09-17T19:49:25.473 に答える
-7

内部使用のためにいくつかのプロパティのサブクラス型が必要な場合、そのようなケースにどのように対処しますか?

プロパティは明示的に内部使用向けではなく、パブリック インターフェイスのメンバーです。

内部値が必要な場合は、メンバー フィールドを定義し、プロパティのセッターをオーバーライドして内部値を設定します。

于 2012-09-17T19:00:37.210 に答える