2015-08-21 7 views
4

Я недавно представил отчет об ошибке Apple, но я подумал, что я буду задавать вопрос в любом случае, если я пропущу что-то очевидное. В Objective-C, следующий вызов прекрасно работает на 64-битной системы, но бросает NSInvalidArgumentException на 32-битной системе:Почему setValue: forKey: сбой в 32-битной системе, но не 64-битный?

[self setValue:@"true" forKey:@"flag"]; 

Свойство "флаг" является BOOL:

@property BOOL flag; 

Кроме того, вызов отлично работает в Swift/32-бит, где свойство является Bool:

var flag: Bool = false 

Аналогичным образом, этот вызов отлично работает в Swift на 64-битной системе, но бросает NSInvalidArgumentException на 32-битной системе ("Inde х»является Int):

setValue("2", forKey: "index") 

Но она отлично работает в Objective-C/32-бит, где свойство является NSInteger.

Я бы ожидал, что эти вызовы будут работать корректно независимо от языка или архитектуры процессора. Кто-нибудь знает, почему они не могут?

+0

Код, который вы отправили, не использует 'BOOL' на всех, кроме двух строк. Код, который вы отправили, не будет вызывать ошибки при описании. – rmaddy

+0

Можете ли вы привести еще несколько примеров кода, где он работает и не работает? Как указывает @rmaddy, ваш код ничего не показывает о BOOL. – brandonscript

+0

Свойство «flag» определяется как BOOL. Вы не знакомы с KVC? –

ответ

4

Ответ есть в комментариях, если вы объедините их все ...

setValue:forKey: делает не требуют NSNumber/NSValue для примитивных типизированных свойств, но, как правило, проходят один.

Наблюдаемые выпуски не относятся к 64-разрядным и 32-разрядным либо, примерный код может также работать на 64-разрядных системах.

Это все вниз к природе BOOL и является ли это char или bool, как комментарий говорит - и это зависит от целого ряда вещей (от Xcode 6.4 работает на 10.10.5):

/// Type to represent a boolean value. 
#if !defined(OBJC_HIDE_64) && TARGET_OS_IPHONE && __LP64__ 
typedef bool BOOL; 
#else 
typedef signed char BOOL; 
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
// even if -funsigned-char is used. 
#endif 

setValue:forKey при установке примитивного набранного свойства < типа > вызовов - <type>Value на любой объект, он передается.

BOOL Если это char он называет - charValue и NSString не имеет такой метод - так потерпеть неудачу.

Если BOOL является bool, он называет - boolValue, а NSString имеет, что все это хорошо.

Простое исправление:

@property bool flag; 

и что должно работать везде, и есть дополнительный бонус, который будет flagвсегда быть истина/ложь, да/нет, 1/0, а не один из других 254 возможностей это char бывает.

Просто подумайте, как бы разные вещи были бы, если бы дизайнеры C не скупились и на самом деле включали настоящий булевский тип с самого начала ...

+0

"setValue: forKey при настройке примитивного типизированного свойства вызовов - Значение для любого объекта, который передается" - это из документов KVC? –

+0

Это выглядит правильно. Из документации Apple: «... setValue: forKey: определяет тип данных, требуемый соответствующей переменной доступа или экземпляра для указанного ключа.Если тип данных не является объектом, тогда значение извлекается из переданного объекта с использованием соответствующего метода значения . » –

+0

Так что это объясняет, почему это не удается, когда BOOL определяется как символ. Я все еще не уверен, почему он не работает для Swift Int, хотя мне придется заглянуть в это немного больше (если кто-то уже не знает ответ и не хочет его делиться). –