3

クラス拡張の大きな利点の 1 つは、クラス拡張を使用すると、ヘッダー ファイルで読み取り専用プロパティを宣言し、クラス拡張でこのプロパティを readwrite プロパティとしてオーバーライドできることです。以下のように:

//SomeClass.h

@interface SomeClass : NSObject
{
    NSInteger someInt;   //with modern runtime you can omit this line
}
@property (readonly) NSInteger someInt;
@end

//SomeClass.m
@interface SomeClass ()
@property (readwrite) NSInteger someInt;
@end

@implementation SomeClass
@synthesize someInt;
@end

ただし、最新のランタイムを使用する場合は、クラス拡張でまったく新しいプロパティを宣言することもできます (存在しない場合は、そのプロパティの iVar も生成します)。

//SomeClass.h

@interface SomeClass : NSObject
{
}
@end

//SomeClass.m
@interface SomeClass ()
@property (readwrite) NSInteger someInt;
@end

@implementation SomeClass
@synthesize someInt;
@end

これが私の質問です。クラス拡張でまったく新しいプロパティを宣言すると、どういうわけか副作用があると思います。クラス拡張はヘッダー ファイルにない可能性があり、クラスをサブクラス化する他の誰かがその「秘密のプロパティ」について知らない可能性があるためです。そして、彼がその「秘密のプロパティ」と同じ名前のプロパティを宣言した場合。そして、この新しいプロパティの getter メソッドと setter メソッドは、スーパー クラスのメソッドをオーバーライドします。これは問題ではありませんか?そして、なぜ現代のランタイムはそのようなことが起こるのを許すのでしょうか?

編集 このトピックについて別の質問を投稿しました。チェックしてください: クラス拡張 (Ojbective-C) で新しいプロパティを宣言するリスク、解決方法は?

4

1 に答える 1

6

クラス拡張で新しいプロパティを宣言するのは悪い習慣だとは思いません。私はこれをある程度の頻度で行います。最初にヘッダーに readonly プロパティを含める唯一の理由は、他のクラスが値を取得できるようにするためですが、変更できるのは自分だけです。多くの場合、その ivar は他のクラスには関係なく、実装の詳細にすぎません。そのため、ヘッダー ファイルには配置されません。

この ivar をプライベート プロパティ (クラス拡張でのみ宣言される新しいプロパティ) として実装することは、便利なメモリ管理ボイラープレート コードを抽象化できるため、依然として有用です。残念ながら、Objective C では名前の衝突は避けられない事実です。Apple は、メソッド名との衝突を防ぐために、従う (または従わない) べきかなり明確な命名規則を用意しています。そのプライベート プロパティで目に見えないように作成したゲッターとセッターとの衝突が心配な場合は、それらのプライベート プロパティ名の命名規則を採用し、強迫観念に従ってくださいプライベート プロパティを実装するときに使用します。これが Objective C で行う最善の方法ですが、個人的には、メリットがリスクを上回ると思います。

于 2011-04-12T18:42:08.977 に答える