最近在使用Cocoa之后转向iOS,我惊讶地得到一个带有以下错误的SIGABRT:“ - [UIDeviceRGBColor copyWithZone:]:无法识别的选择器发送到实例...”我在UIColor上调用了“copy”。
我查看了类引用,并且,zits,UIColor不采用任何协议,与NSColor相反。
现在,这不是什么大问题。我只是试图通过主动拥有一个颜色实例来提高效率,以便在使用后立即丢弃它。但我认为Apple在iOS中省略垃圾收集器背后的目的是鼓励开发人员完全按照我的目的去做,以便在内存不足,电池挑战的便携式设备上保持精简内存配置文件。
有关Apple理由的任何想法,或者我的假设是否存在错误?
答案 0 :(得分:5)
我不明白为什么你认为实施NSCopying
协议会“鼓励主动内存管理”。
由于UIColor
是不可变的(它不实现任何改变其内部状态的方法),因此没有必要复制。如果你想保留它,只需retain
,当你完成时release
就可以了。不需要任何其他东西。
如果您真的想要,可以在类别中添加复制:
@implementation UIColor (Copying) <NSCopying>
- (id)copyWithZone:(NSZone *)zone
{
return [self retain];
}
@end
但显然这并没有给你任何新的功能。显然,Apple认为在实施该课程时并不值得。
答案 1 :(得分:3)
我的应用需要在iOS5(UIColor>>#copyWithZone
不存在)和iOS6 +(UIColor>>#copyWithZone
存在)上工作,所以我想出了以下内容:
@implementation UIColor(ios5CopyWithZone)
+ (void)initialize
{
// iOS5 dosn't include UIColor>>#copyWithZone so add it with class_addMethod.
// For iOS6+ class_addMethod fails as UIColor>>#copyWithZone already exists.
Class klass = [UIColor class];
Method methodToInstall = class_getInstanceMethod(klass, @selector(ios5CopyWithZone:));
class_addMethod(klass, @selector(copyWithZone:), method_getImplementation(methodToInstall), method_getTypeEncoding(methodToInstall));
}
// UIImage is immutable so can just return self.
// #retain to ensure we follow mem-management conventions
-(id)ios5CopyWithZone:(NSZone *)__unused zone
{
return [self retain];
}
@end
代码尝试使用运行时的UIColor>>#copyWithZone
添加class_addMethod
。我不知道这是否比直接在类别中实现UIColor>>#copyWithZone
更好,但是阅读Apple的Avoid Category Method Name Clashes意味着重新实现现有的框架方法(UIColor>>#copyWithZone
是不好的做法在iOS6中)。但是我意识到+initialize
可能会践踏框架的+initialize
。