我想为NSNumber类添加一个属性,所以我必须将它子类化.文档说明我必须覆盖所有NSValue原语方法.由于NSValue文档没有说明哪些方法是原始方法,我认为这两个方法可能是实例化的原始方法:
– initWithBytes:objCType:
+ valueWithBytes:objCType:
Run Code Online (Sandbox Code Playgroud)
所以我把我的课程改为:
@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
Run Code Online (Sandbox Code Playgroud)
但是当我调用[NSNumber numberWithBool:YES]时,我仍然得到一个_NSCFBoolean类,并且不调用"基本方法".我怎样才能弄清楚哪些方法被认为是原始的?
您不需要子类NSNumber以添加属性.您可以使用关联引用更轻松地添加属性.子类化NSNumber非常棘手,因为它是一个类集群.
编辑:@Remco在他对@diablosnuevos的评论中提出了一个重要的观点,我想在答案中提出:
是的,我最终通过反复试验创建了一个子类,因为返回的NSNumbers是共享实例,因此也共享存储关联的引用. - Remco Poelstra 5月16日9:09
这是一件非常重要的事情要记住.NSNumber将整数从-1缓存到12并将它们视为单例.在OSX 10.7中,NSNumber实现为标记指针(没有挖掘相关引用的含义).关键是虽然相关的引用非常有用,但可能存在会烧毁你的底层实现细节.
这里更深刻的教训是,在任何情况下,子类化或扩充NSNumber 可能都不是一个好主意.NSNumber是一个非常低级的对象.建立另一个拥有一个类的类NSNumber似乎肯定更好,就像NSAttributedString拥有一个NSString而不是扩展一样NSString.
我不知道这里要解决的问题的具体细节,但遇到的问题是一个有趣的教训.
我发现上面的大多数答案都是不可接受的.很多时候,子类化可能是最好的设计选择.你得到_NSCFBoolean的原因是因为这就是方便方法numberWithBool:的目的 - 它方便地为你提供了一个具有正确私有子类的NSNumber.你应该编写自己的便利方法aka +(NSNumber*)numberWithMultiple ...
编辑:注意评论中的警告!对于许多类来说,这是一个很好的解决方案;它可能对 NSNumber、NSString 以及其他类似 NSArray 等不利,因为它们出于性能原因在幕后进行魔法,可能会导致意外行为,例如共享实例。
如何避免子类化的痛苦,而是用类别来扩展类?
看看这里:http://oleb.net/blog/2011/05/faking-ivars-in-objc-categories-with-associative-references/
| 归档时间: |
|
| 查看次数: |
1504 次 |
| 最近记录: |