Objective c 设置UIColor属性时KVC调用componentRGBA方法的实现

Objective c 设置UIColor属性时KVC调用componentRGBA方法的实现,objective-c,nsstring,uicolor,key-value-coding,Objective C,Nsstring,Uicolor,Key Value Coding,我有一个名为color的UIColor属性类,我想通过字符串设置此属性: [label setValue:@"1.0 0.5 0.0 1.0" forKey:@"color"]; 我知道我需要将字符串转换为UIColor。我注意到KVC调用了一个名为“componentRGBA”的方法,我想在这里执行转换。因此,我在NSString上添加了一个category方法: -(UIColor*) componentRGBA { CIColor* ciColor = [CIColor colo

我有一个名为color的UIColor属性类,我想通过字符串设置此属性:

[label setValue:@"1.0 0.5 0.0 1.0" forKey:@"color"];
我知道我需要将字符串转换为UIColor。我注意到KVC调用了一个名为“componentRGBA”的方法,我想在这里执行转换。因此,我在NSString上添加了一个category方法:

-(UIColor*) componentRGBA
{
    CIColor* ciColor = [CIColor colorWithString:self];
    UIColor* uiColor = [UIColor colorWithCIColor:ciColor];
    return uiColor;
}
方法被调用。但是,
self
似乎不是有效的NSString对象,因为对colorWithString:的调用在EXC\u BAD\u访问中崩溃,发送
self
NSObject消息(类、说明等)的每次尝试也会崩溃

我怀疑componentRGBA的方法签名不正确,因此self实际上不是string对象。虽然我无法通过谷歌搜索这个方法找到任何参考

如何正确实现组件RGBA,以便在通过KVC将UIColor属性设置为NSString*值时自动执行颜色转换

更新:

有趣的是,当我在componentRGBA方法中执行此操作时:

CFShowStr((__bridge CFStringRef)self);
我收到消息:

这是一个NSString,不是CFString

所以它应该是一个NSString*但是我不能调用它的任何方法而不崩溃

这个简单的测试例如崩溃:

NSLog(@"self = %@", [self description]);
崩溃发生在objc_msgSend中,代码为1,地址为0xFFFFFF(地址随时间而变化)

此外,当我没有实现组件RGBA时,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
我在您的示例项目(现已删除)的帮助下解决了这个问题 问题。关键的一点是(正如我们可以看到的那样 检查堆栈回溯)通过调用
componentRGBA
方法
objc\u msgSend\u stret()
,这意味着它返回一个
结构
,而不是一些
id

您考虑过一个方法或宏来解析字符串吗?是的,但我必须特别检查接收属性是否为UIColor类型,并添加一个特殊的大小写处理来将字符串转换为UIColor,而不是仅仅依靠KVC来执行转换正如需要的那样,我的问题是没有进行任何转换。它只需获取字符串并将其分配给UIColor属性,因为这两个属性都是对象,并且字符串被视为颜色会因为明显的原因而破坏环境。@LearnCos2D:不客气,这很有趣我刚刚注意到,
struct rgba
必须使用
float
,而不是
CGFloat
。否则它将在64位上崩溃。我将相应地更新答案。我在CCColor中实现了这个方法,现在可以用它代替UIColor。这太棒了,省去了我编写一堆属性设置器/获取器来进行转换的麻烦。@learncos2d:但请记住,您依赖的是未记录的实现细节……我一定会记住这一点。现在,即使在使用KVC的情况下,也能够将几乎任何特定对象转换为UIColor/NSColor,这真是太棒了。这是学术上的甜蜜。。。。。我从来没有走得够远,以致于
objc\u msgSend\u stret()
…+1。。我希望明天苹果能为此写上几句话,这样它就可以“记录在案”。甚至连“Description:componentRGBA.如果需要,可以使用它。可用性:iOS(7.0及更高版本)。”。。