2010-01-04 4 views
3

Каков наилучший способ обработки булевых значений, которые происходят из настройки UISwitch, и хранятся в NSMutableDictionary, который сохраняется в каталоге пользователя в качестве постоянных настроек? В частности, каков наилучший способ сохранить логические значения, отличные от числовых значений в NSMutableDictionary, которые записываются и читаются из файловой системы?Лучший способ справиться с постоянными булевыми в plist?

========

добавил: Благодаря Adrian и Бена. Таким образом, результат заключается в том, что если он хранится через [NSNumber numberWithBool:] (это то, что я делал), нет никакого удобного способа определить, возникло ли это значение как логическое значение, правильно?

Вторая часть этого заключается в том, что NSMutableDictionary, который я храню, изначально создается путем создания его с помощью plist с булевыми значениями. Эти значения имеют класс NSCFBoolean при первом чтении. Сейчас моя стратегия заключается в сравнении значения, с которым я работаю в словаре, с соответствующей записью в plist.

Причина в том, что я создаю элементы интерфейса «на лету», чтобы позволить пользователю манипулировать этими значениями, и я связываю булевы с UISwitch. Если я потеряю исходный класс, преобразовывая его в число, я получаю неуместный элемент пользовательского интерфейса.

Я рассматриваю замену массивов как сохраненное значение, где первым значением является сохраненное значение, а остальные записи - это выбор: где существуют два варианта, он рассматривается как логический ... в других случаях, они служат в качестве значений выбора. Но это кажется громоздким, если оно надежным.

Любые идеи приветствуются ...

+0

Да, есть способ: использовать сообщение «objCType» в NSNumber. Он возвращает строку C: «q» для целых чисел, «c» для booleans, «d» для парных. Я отредактировал свой ответ ниже с помощью фрагмента кода, который показывает, как вы можете это видеть. –

ответ

11

значения BOOL сериализуются как экземпляры NSNumber, созданных с помощью numberWithBool NSNumber в: статический метод:

BOOL ok = YES; 
NSNumber *value = [NSNumber numberWithBool:ok]; 

// ...later... 

BOOL answer = [value boolValue]; 

Там нет другого способа сериализации значения BOOL. В plist, который генерируется, если сохранено как XML, значения BOOL отображаются как < true/> и < false/> объектов.

(издание, 17 января 2010)

После моего комментария выше, этот фрагмент кода может помочь идентифицировать различные подтипы экземпляров NSNumber, когда они загружаются в память, используя сообщение «objCType»:

NSString *path = [[NSBundle mainBundle] pathForResource:@"untitled" 
               ofType:@"plist"]; 
NSArray *array = [NSArray arrayWithContentsOfFile:path]; 

for (id item in array) 
{ 
    NSLog(@"%@", [NSString stringWithCString:[item objCType] 
            encoding:NSUTF8StringEncoding]); 
} 

Где untitled.plist имеет такую ​​структуру:

<plist version="1.0"> 
<array> 
    <integer>123</integer> 
    <true/> 
    <real>1.2</real> 
</array> 
</plist> 

В этом случае выполнение указанного выше кода дает следующее:

2010-01-17 17:04:35.100 Untitled[62206:207] q 
2010-01-17 17:04:35.101 Untitled[62206:207] c 
2010-01-17 17:04:35.102 Untitled[62206:207] d 

Возможно, существует другой способ получить внутренний тип данных, хранящихся в NSNumber, но это, похоже, делает трюк.

+1

Только дополнительная информация: 'q' означает 64-разрядное целое число со знаком,' c' означает 'BOOL', который является' typedef'-ed для 'char' в ObjC, а' d' означает 'double'. – kennytm

+0

Спасибо! Я также видел «i» (для 32-битных целых чисел, я полагаю). Есть ли ссылка для этих значений? Я не нашел в документации, связанной с Xcode. –

+0

Глупо мне, я нашел ответ ... в ссылке класса NSNumber :) «Как и в любом кластере классов, если вы создаете подкласс NSNumber, вы должны переопределить примитивные методы своего суперкласса NSValue. , существует ограниченный набор возвращаемых значений, возвращаемый вашей реализацией метода objCType NSValue, чтобы воспользоваться абстрактными реализациями не-примитивных методов. Допустимыми значениями возврата являются «c», «C», s "," S "," i "," I "," l "," L "," q "," Q "," f "и" d "." –

3

Вы можете также использовать константы kCFBooleanTrue и kCFBooleanFalse, хотя добавить их к NS-нибудь вам нужно, чтобы бросить их в качестве идентификаторов:

[myDictionary setObject: (id) kCFBooleanTrue forKey: @"am_I_awesome"]; 
1

CFBoolean объекты используются для представления логических значений в CoreFoundation плиты и коллекции.Использование CFBoolean обеспечивает максимальную совместимость, особенно при общении с сторонним программным обеспечением.

Следующая функция возвращает значение объекта CFBoolean в качестве булева типа C.

Boolean CFBooleanGetValue (CFBooleanRef boolean); 

Следующие константы обеспечивают доступ к истинным и ложным объектам.

const CFBooleanRef kCFBooleanTrue; 
const CFBooleanRef kCFBooleanFalse;