4

これが私がやりたい比較操作です:

// foobar is the name of an ivar on some class
// i.e. NSDate *foobar;
const char *ivarType = [self getTypeForInstanceVariableWithName:@"foobar"];
const char *objType  = @encode(NSDate);

if (strcmp(ivarType, objType) == 0) {
    //set value 
} 

NSLog(@"comparing %s with %s", ivarType, objType);

ヘルパーメソッド:

- (const char*)getTypeForInstanceVariableWithName:(NSString *)name {
     return ivar_getTypeEncoding(class_getInstanceVariable([self class], [name cStringUsingEncoding:NSUTF8StringEncoding]));
}

NSLogの結果:

comparing @"NSDate" with {NSDate=#}

@encodeがivar_getTypeEncoding()とは異なる型構文を返すのはなぜですか?このタイプの決定を達成するためのより良い方法はありますか?私はここで何かが欠けているに違いありません...ありがとう!

4

1 に答える 1

5

ivar_getTypeEncoding()を使用するときは、最初の文字に注意する必要があります。例を見てみましょう:

プリミティブ型の場合、最初のcharがすべて取得され、intの場合は「i」、charの場合は「c」、unsignedlonglongの場合は「Q」などになります。

オブジェクトとクラスの場合、例のようにさらに多くの情報が得られる可能性がありますが、最初の文字は必要なものです。たとえば、オブジェクトの場合は@、クラスの場合は#、セレクターの場合は:です。

これらのタイプについては、ここで読むことができます。_C_ID、_C_CLASSなどのように、比較時に定数を使用することもできます。runtime.hで戦利品を用意します。

C配列はもっとトリッキーなようですが、それを回避できると確信しています。

コードの問題の1つは、NSDateオブジェクトではなく、NSDateクラスの型エンコーディングを取得していることです。したがって、@ encode(NSDate)と比較する代わりに、@ encode(NSDate *)と比較してください。

このタイプのコードが実際に動作していることを確認するには、たとえばAdiumのコードを見てください。

于 2012-04-15T00:55:52.877 に答える