いくつかのConverterクラスから継承するコンバーター/作動オブジェクトのディクショナリーを維持するコンテキスト「ファクトリー」を書いています。このクラスにはメソッドがあります:
- (Class)classResponsibility
または、StringConverterクラスがメソッドを次のように実装するような類似のもの:
- (Class)classResponsibility {
return [NSString class];
}
次に、そのコンバーターを辞書に格納するために、私は次のようなことを望んでいました:
[converters setValue:stringConverter forKey:[stringConverter classResponsibility]];
しかし、コンパイラーは、型「Class」がsetValue:forKey:メソッドの引数2の無効なパラメーター型であることを報告します。キーをクラスの名前( "NSString")として設定することは避けたかったのですが、それが最善の解決策である場合は、それを使用します。
NSString
sのみをキーとして取るsetValue:forKey:
を使用しています。代わりにsetObject:forKey:
を使用する必要があります。クラスオブジェクト(クラスオブジェクトへのポインタはClass
型として渡すことができます)は本格的なObjective-Cオブジェクトです(クラスオブジェクトはメタクラスのインスタンスであり、クラスオブジェクトですべてのNSObject
メソッドを使用できます。メタクラスの詳細については here )を参照してください。そのため、オブジェクトが使用される場所ならどこでも使用できます。
辞書のキーのもう1つの要件は、それらがコピーをサポートすることです(つまり、copyWithZone:
メソッドを持っています。クラスオブジェクトはこのメソッドをサポートしていますか?実際にはサポートしています。NSObjectクラスは、を定義します) class method+copyWithZone:
、その documentation は、「NSDictionaryオブジェクトへのキーとしてクラスオブジェクトを使用できるようにする」ことを明示的に示しています。あなたの質問に答えてください。
他のオプションは、[NSValue valueWithNonretainedObject:yourObjectHere]
を使用して、文字列以外のものからキーを構築することです。私は同様の問題に遭遇し、CoreDataオブジェクトをキーとして使用し、他の何かを値として使用したいと考えました。このNSValue
メソッドは完璧に機能し、私はそれが本来の意図であったと信じています。元の値に戻すには、nonretainedObjectValue
を呼び出します。
_-setValue:forKey:
_は、2番目のパラメーターとしてNSString
を取るように文書化されています。 NSStringFromClass()
およびNSClassFromString()
をアダプターとして使用する必要があります。
ClassオブジェクトはNSDictionaryで完全に適切なキーを作成しますが、NSDictionaryに基づいてモデル化されたNSMapTableについて言及する価値はありますが、キーや値として使用するのに適したオブジェクトの種類に関してより柔軟性があります documented 弱参照と任意のポインタをサポートします。
SetValue:forKey:ではなくsetObject:forKey:メソッドを探していました。 setObject:forKey:のメソッドシグネチャは、(id)を両方のパラメータータイプとして受け入れ、はるかに適しています。
私はちょうど同じエラーメッセージで同様の状況を切り出しました:
[tempDictionary setObject:someDictionary forKey:someClass];
私がしたことは、NSCopying
にsomeClass
プロトコルを実装することだけでした。
- (id)copyWithZone:(NSZone *)zone
{
id copy = [[[self class] allocWithZone:zone] init];
[copy setId:[self id]];
[copy setTitle:[self title]];
return copy;
}
キーとして使用するためにsomeClass
のコピーが作成されていたことが起こっていたと思いますが、私のオブジェクトはそれ自体をコピーする方法を知りませんでした(NSObject
から派生)スーパークラスにcopyWithZone
がありませんでした)はげました。
私のアプローチで見つけた1つのことは、オブジェクトをキーとして使用することです。オブジェクトが既にインスタンス化されていない限り、私は常にallKeys
を呼び出すか、ディクショナリを列挙するだけです。
[これを書いてから、クラスをキーなどとして保存したいと思います。 SOを検索しているときに答えが見つかれば、多くの時間を節約できたので、これはそのままにしておきます。その時、私はこのようなものを見つけませんでした。]
次のように、クラスをNSDictionary
のキーとして使用できます。
@{
(id)[MyClass1 class] : @1,
(id)[MyClass2 class] : @2,
(id)[MyClass3 class] : @3,
(id)[MyClass4 class] : @4,
};
または次のようにも:
@{
MyClass1.self : @1,
MyClass2.self : @2,
MyClass3.self : @3,
MyClass4.self : @4,
};