2012-03-09 5 views
38

クラス階層を設計するときに、サブクラスに新しいinitWithSomeNewParamメソッドが追加されることがあり、スーパークラスから継承した古いinitメソッドへの呼び出しを無効にすることが望ましい場合があります。他のプログラマが-initを呼び出さないようにするための最良の方法

まず最初に質問hereを読んでいます。提案されている選択肢は、実行時に例外をスローするためにinitを上書きするか、プロパティのデフォルト値を上書きして設定します。私の場合は、デフォルト値を提供するのではなく、古いメソッドを呼び出すべきではないことを明示し、代わりに新しいメソッドを使用する必要があります。

ランタイム例外は問題ありませんが、コードがデバッグされていない限り、チーム内の他のプログラマーが古いメソッドが使用される予定がないことに気付くことはできません。

私が正しいとすれば、メソッドを「プライベート」としてマークする方法はありません。だから、コメントを追加するだけでなく、これを行う方法はありますか?

ありがとうございます。

+0

コメントと例外 - これ以外にもできることはありません。 –

答えて

103

あなたが明示的に自分のヘッダファイルで使用不能であるとして、あなたのinitをマークすることができます

- (id) init __unavailable; 

か:

- (id) init __attribute__((unavailable)); 

後の構文を使用すると、あなたもすることができます理由を挙げる:

- (id) init __attribute__((unavailable("Must use initWithFoo: instead."))); 

コンパイラは、誰かがそれを呼び出そうとすると、エラー(警告ではない)を発行します。

+1

これは仕事です。ありがとう! –

+2

+1私はこれが存在するのか分からなかった。良いですね! – darvids0n

+2

非常に良い、それについても知らなかった。 –

1

フラグは廃止されましたか? 開発者は開発者になりますが、私たちをすべて止めることはできません! ;-)

How do I flag a method as deprecated in Objective-C 2.0?

+1

しかし、コンパイラはまったく文句を言っていません。私はXcodeを明るく点滅している赤いXDで強調表示したい。 –

0

initWith:Stuffと:OtherStuffは、便利なコンストラクタであってはなりません。

それらが効果的に常に事前に定義された状態でオブジェクトを返し、[オブジェクトinitWithStuff:ものは]を[オブジェクトINIT]

self = [self init]; 

if(self) 
{ 
    self.stuff = Stuff; 
    self.other = OtherStuff; 
} 

を呼び出すべきことを

オーバーライドものと予め規定された状態でオブジェクトを返します。

基本的に私が得意とするのは、特にオブジェクトの初期化を妨げる悪い習慣です。将来、あなたのサブクラスをサブクラス化するときは特にそうです。

+0

私は違います。私はポスターが望んでいるものが完璧な意味を成していると思います(そして、私はランタイムアサーションでもそうしました)。時には単に空のオブジェクトを割り当てるのは意味がなく、デフォルトを与えることはできません。特に、インスタンスが不変であると考えられる場合、またはクラス・クラスターである場合。 – DarkDust

+0

はい、私はそれが悪い習慣であることを知っていますが、いくつかのクラスではデフォルト値が意味をなさない。 –

+0

その場合、+(class)classWithPredefinedStuff :(Stuff *)stuff; –

-1

ソートあなたのクラスにprivate extensionを定義することによってメソッドを「プライベート」とマークすることができます。あなたの.hで

:あなたは

@interface MyClassName 
- (void)initWithSomeNewParam:(id)param; 

。M:誰が添付XCodeのセッションでプロジェクトを実行しているとき、彼らは代わりにinitWithSomeNewParam:を使用し、initを使用しないでください」と同様、コンソール出力が表示されますように

@interface MyClassName() 
- (void)init; 
@end 

ます。またNSLog文を追加することができます。 "これは、Apple自身が歴史的に非難されたAPI呼び出し(およびドキュメントで非推奨となっているマーキング)に取っていたアプローチです。投稿@DarkDustものに追加するには

+0

'NSObject'レベルで定義されているため、' init'では動作しません。 – DarkDust

+0

私は違います。この方法の問題は、このように非公開にすることは、誰もがオブジェクトがドキュメントから 'init'できることを知っているように、識別可能な効果*がないことです。そしてXCodeはこのような理由で、おそらくメソッドの自動補完でそれを表示します。 – darvids0n

4

、あなたは、代わりに、ユーザは、このクラスのインスタンスにinitを呼び出そうとした場合に、このエラーがスローされますUNAVAILABLE_ATTRIBUTE

- (id)init UNAVAILABLE_ATTRIBUTE; 

を使用することができます。

関連する問題