Почему этот код ведет себя по-разному на 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-битным.

Другие вопросы по тегам