我有一个名为 color 的 UIColor 属性的类,我想通过字符串设置此属性:
[label setValue:@"1.0 0.5 0.0 1.0" forKey:@"color"];
我知道我需要将字符串转换为 UIColor。我注意到 KVC 调用了一个名为“componentRGBA”的方法,这是我想要执行转换的地方。所以我在 NSString 上添加了一个类别方法:
-(UIColor*) componentRGBA
{
CIColor* ciColor = [CIColor colorWithString:self];
UIColor* uiColor = [UIColor colorWithCIColor:ciColor];
return uiColor;
}
该方法被调用。然而,self
似乎不是一个有效的 NSString 对象,因为对 colorWithString: 的调用因 EXC_BAD_ACCESS 崩溃,并且每次尝试向 self
发送 NSObject 消息(类、描述)时都会崩溃。等)。
我怀疑 componentRGBA 的方法签名不正确,因此 self 实际上不是字符串对象。虽然我无法通过谷歌搜索此方法找到任何引用。
如何正确实现 componentRGBA
以便在通过 KVC 将 UIColor 属性设置为 NSString* 值时自动执行颜色转换?
更新:
有趣的是,当我在 componentRGBA 方法中执行此操作时:
CFShowStr((__bridge CFStringRef)self);
我收到消息:
This is an NSString, not CFString
所以它应该是一个 NSString* 但我无法在不崩溃的情况下调用它的任何方法。
这个简单的测试例如崩溃:
NSLog(@"self = %@", [self description]);
崩溃发生在 objc_msgSend 中,代码=1,地址=0xffffffff(地址不时变化)。
此外,当我不实现 componentRGBA
时,KVC 会失败并显示以下消息:
-[__NSCFConstantString componentRGBA]: unrecognized selector sent to instance 0xc48f4
最佳答案
这可能只是出于学术兴趣,因为您可能不想依赖 一个未记录的方法,但以下实现似乎有效:
// This structure is returned by the (undocumened) componentRGBA
// method of UIColor. The elements are "float", even on 64-bit,
// so we cannot use CGFloat here.
struct rgba {
float r, g, b, a;
};
@interface UIColor (ComponentRGBA)
-(struct rgba) componentRGBA;
@end
@interface NSString (ComponentRGBA)
-(struct rgba) componentRGBA;
@end
@implementation NSString (ComponentRGBA)
-(struct rgba) componentRGBA
{
CIColor* ciColor = [CIColor colorWithString:self];
UIColor* uiColor = [UIColor colorWithCIColor:ciColor];
return [uiColor componentRGBA];
}
@end
我在您的示例项目(现已删除)的帮助下解决了这个问题
问题KVC: what does the 'componentRGBA' method do when setting a color property? 。关键点是(正如人们可以看到的那样
检查堆栈回溯)通过调用 componentRGBA
方法
objc_msgSend_stret()
,这意味着它返回一个struct
,而不是一些id
。
关于objective-c - 设置 UIColor 属性时 KVC 调用的 componentRGBA 方法的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17974678/