目的C-サブクラス化NSARRAY
-
08-10-2019 - |
質問
私はサブクラスをしようとしています NSArray
, 、しかし、カウントメソッドにアクセスしようとするとアプリがクラッシュします。そんなこと知ってる NSArray
aです クラスクラスター.
- しかし、これはどういう意味ですか?
- NSARRAYをサブクラス化できるようにするための回避策はありますか?
私は単にサブクラスできることを知っています NSObject
そして、私の配列をインスタンス変数として持っていますが、私はむしろサブクラスをしたい NSArray
.
編集:理由:私はカードゲームを作成しています、私はクラスを持っています Deck
どちらがサブクラスです NSMutableArray
いくつかの追加の方法を持っている(-shuffle
, -removeObjects:
, -renew
, など)、そして私はそれがサブクラスにクリーンに見えると思います NSArray
varを持つのではなく。
解決
このようなクラスにカテゴリを追加することの問題は、クラスのすべてのインスタンスが追加の方法を継承することです。それは不要です(すべての配列をシャッフルする必要があるわけではないので)と危険です(あなたが現在言及しているnsarrayが本当にシャッフルされることが期待されていたnsarrayが確かにタイプチェックすることができないため)。
別の方法は、インスタンス変数としてNSMutablearrayを持つ独自のデッキクラスを作成することです。そこでは、必要に応じてデッキ上のアクションを定義することができ、nsmutablearrayを使用しているという事実が実装の詳細になります。これにより、コンパイル時間でタイプチェックを利用でき、クライアントを変更せずにデッキクラスの内部実装を変更できます。たとえば、NSMutadedictionaryがより良いバッキングストアになると何らかの理由で決定した場合、デッキを作成および使用するコードを変更せずに、デッキクラスの実装内でこれらすべての変更を行うことができます。
他のヒント
通常、サブクラス化する必要はありませんが、いずれにせよ、Appleが行った提案は次のとおりです。
NSARRAYのサブクラス しなければならない プリミティブインスタンスメソッドをオーバーライドします
count
とobjectAtIndex:
. 。これらの方法は、コレクションの要素に提供するバッキングストアで動作する必要があります。このバッキングストアでは、静的配列、標準のNSARRAYオブジェクト、または他のデータタイプまたはメカニズムを使用できます。また、代替実装を提供する他のNSARRAYメソッドを、部分的または完全にオーバーライドすることを選択することもできます。
実際にオーバーライドしましたか count
方法?彼らが言うように、あなたはアレイ要素を保持するためにあなた自身のバッキング構造を提供する必要があり、これを考慮して提案された方法をオーバーライドします。
新しい方法を追加し、既存のバッキングストアを使用するだけの場合、より良いアプローチは、NSARRAYにカテゴリを追加することです。カテゴリはObjective -Cの本当に強力な部分です - ココアデフ 一部のサンプルの場合。
NSMutableArray
すでにあります - (void)removeObjectsInArray:(NSArray *)otherArray;
あなたは、可変配列プロパティを備えたNSObjectサブクラスを作成するのが最善です。
この特定のケースでは、アレイを使用してシャッフルします -sortedArrayUsingComparator:
そして、コンパレータをランダムに戻します NSOrderedAscending
また NSOrderedDescending
.
例えば:
NSArray *originalArray; // wherever you might get this.
NSArray *shuffledArray = [orginalArray sortedArrayUsingComparator:
^(id obj1, id obj2) {
return random() % 2 ? NSOrderedAscending : NSOrderedDescending;
}];