4

NSNumber クラスにプロパティを追加したいので、サブクラス化する必要があります。ドキュメントには、すべての NSValue プリミティブ メソッドをオーバーライドする必要があると記載されています。NSValue のドキュメントにはどのメソッドがプリミティブなのかが記載されていないため、これら 2 つはおそらくインスタンス化のためのプリミティブなメソッドであると考えました。

– initWithBytes:objCType:  
+ valueWithBytes:objCType:

だから私は自分のクラスを次のようにしました:

@interface MultipleNumber : NSNumber {  
    NSNumber *_number;  
}  
@property (nonatomic, getter = isMultiple) BOOL multiple;  
@end

@implementation MultipleNumber  
@synthesize multiple=_multiple;  

-(id)initWithBytes:(const void *)value objCType:(const char *)type {  
    self = [super init];  
    if (self) {
        _number=[[NSNumber alloc] initWithBytes:value objCType:type];
    }
    return self;
}

+(NSValue *)valueWithBytes:(const void *)value objCType:(const char *)type {
   return [[[MultipleNumber alloc] initWithBytes:value objCType:type] autorelease];
}

-(void)getValue:(void *)value { [_number getValue:value]; }

-(const char *)objCType { return [_number objCType]; }

@end

しかし、[NSNumber numberWithBool:YES] を呼び出すと、まだ _NSCFBoolean クラスが返され、「プリミティブ メソッド」は呼び出されません。どのメソッドがプリミティブと見なされるかをどのように把握できますか?

4

3 に答える 3

7

NSNumberプロパティを追加するためにサブクラス化する必要はありません。連想参照を使用すると、プロパティをより簡単に追加できます。サブクラス化NSNumberはクラスクラスターであるため、非常に注意が必要です。


編集:@Remcoは、@ diablosnuevosへのコメントの中で、私が答えで呼びかけたかった重要な点を指摘しています。

はい、最終的に試行錯誤でサブクラスを作成しました。返されるNSNumberは共有インスタンスであり、関連付けられた参照の保存も共有されるためです。– RemcoPoelstra5月16日9:09

これは覚えておくべき本当に重要なことです。NSNumber-1から12までの整数をキャッシュし、それらをシングルトンとして扱います。OSX 10.7ではNSNumber、タグ付きポインターとして実装されています(関連する参照の意味については掘り下げていません)。重要なのは、関連する参照は非常に便利ですが、基礎となる実装の詳細が存在する可能性があるということです。

ここでのより深い教訓は、サブクラス化または拡張は、どのような場合でもNSNumber おそらく良い考えではないということです。NSNumber非常に低レベルのオブジェクトです。を拡張するのではなく、を所有するのNSNumberと同じように、を所有する別のクラスを作成する方がほぼ確実に優れています。NSAttributedStringNSStringNSString

ここで解決されている問題の詳細はわかりませんが、発生した問題は興味深い教訓になります。

于 2012-05-02T13:30:03.210 に答える
5

上記のほとんどの回答は受け入れられません。多くの場合、サブクラス化が最良の設計選択である場合があります。_NSCFBoolean を取得する理由は、それが便利なメソッド numberWithBool: が行うように設計されているためです。これは、正しいプライベート サブクラスを持つ NSNumber を便利に提供します。独自の便利なメソッド別名 + (NSNumber*)numberWithMultiple... を作成する必要があります。

于 2012-05-14T16:21:37.123 に答える
4

編集: コメントの警告に注意してください! これは、多くのクラスにとって優れたソリューションです。NSNumber、NSString、およびおそらく NSArray などの他のものには適していない可能性があります。これらは、インスタンスの共有など、予期しない動作につながる可能性のあるパフォーマンス上の理由で舞台裏で魔法を行うためです。

サブクラス化の手間を省き、代わりにクラスをカテゴリで拡張するのはどうでしょうか?

こちらをご覧ください: http://oleb.net/blog/2011/05/faking-ivars-in-objc-categories-with-associative-references/

于 2012-05-02T13:33:43.443 に答える