UIColor 相等性在将其存储在 NSUserDefaults 后失败
UIColor equality fails after storing it in NSUserDefaults
我在 NSUserDefaults
中存储了一个 UIColor
,我遇到的问题是在检索颜色时简单的相等性检查失败(对于我的测试)。有人可以解释为什么这会失败吗?
UIColor *color = [UIColor colorWithRed: 0.922 green: 0.404 blue: 0.024 alpha: 1];
NSData *colorData = [NSKeyedArchiver archivedDataWithRootObject:color];
[[NSUserDefaults standardUserDefaults] setObject:colorData forKey:@"myColor"];
NSData *storedColorData = [[NSUserDefaults standardUserDefaults] objectForKey:@"myColor"];
UIColor *restoredColor = [NSKeyedUnarchiver unarchiveObjectWithData:storedColorData];
if ([color isEqual:restoredColor]) {
NSLog(@"Same color");
} else {
NSLog(@"Not the same color");
}
结果将是 "Not the same color"。在调试器中快速查看将显示颜色相同(RGB 和 alpha 值)。
也许这个问题可以帮到你:
您可以尝试使用 CGColorEqualToColor(color.CGColor, restoredColor.CGColor)
来比较颜色。
如果你NSLog
两种颜色,你会发现两种颜色实际上是一样的!
NSLog(@"Color before: %@", color);
NSLog(@"Color after: %@", restoredColor);
// 2015-04-09 13:19:36.640 test[31149:6236981] Color before: UIDeviceRGBColorSpace 0.922 0.404 0.024 1
// 2015-04-09 13:19:36.641 test[31149:6236981] Color after: UIDeviceRGBColorSpace 0.922 0.404 0.024 1
因此您需要明确比较 UIColor
的每个组件,即 red
、green
、blue
和 alpha
。
看看这个 answer!
有趣的是,如果您记录这两种颜色的哈希值,它们看起来也一样
NSLog(@"Color Hash before: %lu", (unsigned long)[color hash]);
NSLog(@"Color Hash after: %lu", (unsigned long)[restoredColor hash]);
// 2015-04-09 13:59:06.097 test[31299:6252585] Color before: 137311944
// 2015-04-09 13:59:06.097 test[31299:6252585] Color after: 137311944
这样您就可以比较哈希并使其正常工作。
if(color.hash == restoredColor.hash) {
// ...
}
如上面接受的答案所述,当您传入 double
值时,isEqualTo:
不起作用。 float
应改为传递值
UIColor *color = [UIColor colorWithRed:0.922f green:0.404f blue:0.024f alpha:1.0f];
如果你这样声明你的 UIColor:
UIColor *color = [UIColor colorWithRed: (float)0.922 green: (float)0.404 blue: (float)0.024 alpha: (float)1];
两种比较颜色的方法在你的例子中都是return YES:
[color isEqual:restoredColor]
CGColorEqualToColor(color.CGColor, restoredColor.CGColor)
更新:用于比较 UIColor 组件的类别
@interface UIColor (Compare)
- (BOOL)isEqualToColor:(UIColor *)otherColor;
@end
@implementation UIColor (Compare)
- (BOOL)isEqualToColor:(UIColor *)otherColor {
const CGFloat *components = CGColorGetComponents(self.CGColor);
float colorOne[4] = {components[0], components[1], components[2], components[3]};
const CGFloat *otherComponents = CGColorGetComponents(otherColor.CGColor);
float colorTwo[4] = {otherComponents[0], otherComponents[1], otherComponents[2], otherComponents[3]};
return colorOne[0] == colorTwo[0] && colorOne[1] == colorTwo[1] && colorOne[2] == colorTwo[2] && colorOne[3] == colorTwo[3];
}
@end
我在 NSUserDefaults
中存储了一个 UIColor
,我遇到的问题是在检索颜色时简单的相等性检查失败(对于我的测试)。有人可以解释为什么这会失败吗?
UIColor *color = [UIColor colorWithRed: 0.922 green: 0.404 blue: 0.024 alpha: 1];
NSData *colorData = [NSKeyedArchiver archivedDataWithRootObject:color];
[[NSUserDefaults standardUserDefaults] setObject:colorData forKey:@"myColor"];
NSData *storedColorData = [[NSUserDefaults standardUserDefaults] objectForKey:@"myColor"];
UIColor *restoredColor = [NSKeyedUnarchiver unarchiveObjectWithData:storedColorData];
if ([color isEqual:restoredColor]) {
NSLog(@"Same color");
} else {
NSLog(@"Not the same color");
}
结果将是 "Not the same color"。在调试器中快速查看将显示颜色相同(RGB 和 alpha 值)。
也许这个问题可以帮到你:
您可以尝试使用 CGColorEqualToColor(color.CGColor, restoredColor.CGColor)
来比较颜色。
如果你NSLog
两种颜色,你会发现两种颜色实际上是一样的!
NSLog(@"Color before: %@", color);
NSLog(@"Color after: %@", restoredColor);
// 2015-04-09 13:19:36.640 test[31149:6236981] Color before: UIDeviceRGBColorSpace 0.922 0.404 0.024 1
// 2015-04-09 13:19:36.641 test[31149:6236981] Color after: UIDeviceRGBColorSpace 0.922 0.404 0.024 1
因此您需要明确比较 UIColor
的每个组件,即 red
、green
、blue
和 alpha
。
看看这个 answer!
有趣的是,如果您记录这两种颜色的哈希值,它们看起来也一样
NSLog(@"Color Hash before: %lu", (unsigned long)[color hash]);
NSLog(@"Color Hash after: %lu", (unsigned long)[restoredColor hash]);
// 2015-04-09 13:59:06.097 test[31299:6252585] Color before: 137311944
// 2015-04-09 13:59:06.097 test[31299:6252585] Color after: 137311944
这样您就可以比较哈希并使其正常工作。
if(color.hash == restoredColor.hash) {
// ...
}
如上面接受的答案所述,当您传入 double
值时,isEqualTo:
不起作用。 float
应改为传递值
UIColor *color = [UIColor colorWithRed:0.922f green:0.404f blue:0.024f alpha:1.0f];
如果你这样声明你的 UIColor:
UIColor *color = [UIColor colorWithRed: (float)0.922 green: (float)0.404 blue: (float)0.024 alpha: (float)1];
两种比较颜色的方法在你的例子中都是return YES:
[color isEqual:restoredColor]
CGColorEqualToColor(color.CGColor, restoredColor.CGColor)
更新:用于比较 UIColor 组件的类别
@interface UIColor (Compare)
- (BOOL)isEqualToColor:(UIColor *)otherColor;
@end
@implementation UIColor (Compare)
- (BOOL)isEqualToColor:(UIColor *)otherColor {
const CGFloat *components = CGColorGetComponents(self.CGColor);
float colorOne[4] = {components[0], components[1], components[2], components[3]};
const CGFloat *otherComponents = CGColorGetComponents(otherColor.CGColor);
float colorTwo[4] = {otherComponents[0], otherComponents[1], otherComponents[2], otherComponents[3]};
return colorOne[0] == colorTwo[0] && colorOne[1] == colorTwo[1] && colorOne[2] == colorTwo[2] && colorOne[3] == colorTwo[3];
}
@end