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

标签 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 上添加了一个类别方法:

-(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/

相关文章:

iphone - 在iPhone应用程序中保留全局变量的最佳方式

iphone - 使用动态行高时 UITableView 出现间隙

ios - 在 NSString 中查找各种子字符串

iphone - 计算两个 NSString 之间的差异数

swift - 使 UITableViewCell 着色为特定百分比

ios - 在没有 contentView 框架的情况下计算 UITableViewCell 高度的最佳方法

iphone - 在单个 View 中隐藏 iPhone 上的状态栏?

ios - 在 NSData 和 base64 字符串之间转换

ios - 如何将我的 UIButton 背景颜色更新为特定颜色代码 0xff64b5f6

iOS 以编程方式渐变