首页 文章

子类化NSNumber

提问于
浏览
4

我想为NSNumber类添加一个属性,所以我必须将它子类化 . 文档说明我必须覆盖所有NSValue原语方法 . 由于NSValue文档没有说明哪些方法是原始方法,我认为这两个方法可能是实例化的原始方法:

– 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类,并且不调用“基本方法” . 我怎样才能弄清楚哪些方法被认为是原始的?

3 回答

  • 5

    EDIT: Heed the warnings in comments! This is a good solution for many classes; it may not be good for NSNumber, NSString, and possibly others like NSArray etc. because they do behind-the-scenes magic for performance reasons that may lead to unexpected behavior, like sharing instances.

    如何节省自己子类化的痛苦,而是用类别扩展类?

    看看这里:http://oleb.net/blog/2011/05/faking-ivars-in-objc-categories-with-associative-references/

  • 4

    您不需要继承 NSNumber 以添加属性 . 您可以使用associative reference更轻松地添加属性 . 子类化 NSNumber 非常棘手,因为它是一个类集群 .


    编辑:@Remco在他对@diablosnuevos的评论中提出了一个重要观点,我想在答案中提出:

    是的,我最终通过反复试验创建了一个子类,因为返回的NSNumbers是共享实例,因此也共享存储关联的引用 . - Remco Poelstra 5月16日9:09

    这是一件非常重要的事情要记住 . NSNumber 将整数从-1缓存到12并将它们视为单例 . 在OSX 10.7中, NSNumber 被实现为标记指针(没有挖掘相关引用的含义) . 关键是虽然相关的引用非常有用,但可能存在会烧毁您的底层实现细节 .

    这里更深刻的教训是,在任何情况下,子类化或扩充 NSNumber 可能都不是一个好主意 . NSNumber 是一个非常低级的对象 . Build 另一个拥有 NSNumber 的类几乎肯定会更好,就像 NSAttributedString 拥有 NSString 而不是扩展 NSString 一样 .

    我不知道这里要解决的问题的具体细节,但遇到的问题是一个有趣的教训 .

  • 7

    我发现上面的大多数答案都是不可接受的 . 很多时候,子类化可能是最好的设计选择 . 你得到_NSCFBoolean的原因是因为这是方便的方法numberWithBool:设计用来做 - 它方便地给你一个带有正确私有子类的NSNumber . 你应该编写自己的便利方法aka(NSNumber *)numberWithMultiple ...

相关问题