Почему этот код ведет себя по-разному на 64-битных сборках? (iOS / UIColor / UIKeyedArchiver)
Код:
UIColor * color = [UIColor colorWithHue:0.3 saturation:0.2 brightness:0.2 alpha:1];
CGFloat r,g,b,a;
[color getRed:&r green:&g blue:&b alpha:&a];
NSData * colorData = [NSKeyedArchiver archivedDataWithRootObject:color];
UIColor * unarchivedColor = [NSKeyedUnarchiver unarchiveObjectWithData:colorData];
[unarchivedColor getRed:&r green:&g blue:&b alpha:&a];
Как и ожидалось в 32-битных сборках, unarchivedColor и color имеют абсолютно одинаковые значения rgb. На билдах arm64 unarchivedColor и цвет начинают различаться в пределах 9-го знака после запятой.
Другими словами, архивирование / разархивирование UIColor изменяет цвет на arm64... Мне нужно, чтобы этого не произошло. Что здесь происходит и есть ли способ это исправить?
3 ответа
Через службу технической поддержки Apple подтвердили, что это ошибка, относящаяся к классу архивации на arm64. Вместо этого они предложили создать собственный класс архиватора.
Разница, вероятно, в том, что на 32-битной, CGFloat
это float
в то время как под 64-битным это double
,
Попробуйте использовать double
вместо CGFloat
, Или просто примите тот факт, что под 64-разрядной версией вы получите более высокие значения точности.
Это больше не проблема (или, возможно, никогда не было проблемой).
UIColor * color = [UIColor colorWithHue:0.3 saturation:0.2 brightness:0.2 alpha:1];
NSData * colorData = [NSKeyedArchiver archivedDataWithRootObject:color];
UIColor * unarchivedColor = [NSKeyedUnarchiver unarchiveObjectWithData:colorData];
CGFloat r, g, b, h, s, a;
[color getHue:&h saturation:&s brightness:&b alpha:&a];
NSLog(@"HSBA %f %f %f %f", h, s, b, a);
[unarchivedColor getHue:&h saturation:&s brightness:&b alpha:&a];
NSLog(@"unarchived HSBA %f %f %f %f", h, s, b, a);
[color getRed:&r green:&r blue:&b alpha:&a];
NSLog(@"RGB %f %f %f %f", r, g, b, a);
[unarchivedColor getRed:&r green:&r blue:&b alpha:&a];
NSLog(@"unarchived RGB %f %f %f %f", r, g, b, a);
Результаты (в формате)
HSBA 0.300000 0.200000 0.200000 1.000000
unarchived HSBA 0.300000 0.200000 0.200000 1
RGB 0.200000 0.000000 0.160000 1.000000
unarchived RGB 0.200000 0.000000 0.160000 1.000000
Тем не менее, построение UIColor
объект, использующий значения HSBA без arm64
выбран, архивировать его, а затем разархивировать его под arm64
приведет к разным значениям HSBA, когда они будут восстановлены из-за разных уровней точности с 64-битным.