#iphone #objective-c #ios #cocoa-touch
#iPhone #objective-c #iOS #cocoa-touch
Вопрос:
Как я могу поместить значение по умолчанию в свою строку, если получаю данные из пустого ключа / значения в словаре.
итак [myObject setMyString:[dictionary valueForKey:@"myKey"]];
Итак, если бы я это сделал NSString *newString = myObject.myString
, я бы получил unrecognized selector error
.
Итак, мне просто нужен способ вставить строку по умолчанию, если значение ключа пустое;
Комментарии:
1. Я не уверен, о чем вы спрашиваете, можете ли вы уточнить?
2. Вы не можете получить нулевое значение из словаря. Если возвращается значение nil, это означает, что ключ не существует в словаре. Если вы хотите сохранить (концептуальное) нулевое значение в словаре, вы должны использовать объект NSNull .
Ответ №1:
Если dictionary
это a NSDictionary
, вам, вероятно, следует использовать objectForKey
as valueForKey
используется для KVC. Это работает NSDictionary
, но может вас укусить, если ключ столкнется с каким NSDictionary
-либо ключом KVC, например, «@allKeys» или «@count».
Я думаю, что самое короткое, вероятно, сделать:
[dictionary objectForkey:@"myKey"] ?: @"defaultValue"
Существует один ужасный способ злоупотребления существующими методами словаря для получения ключа get by или возврата значения по умолчанию, если вы по какой-либо причине не хотите использовать условие…
[[dictionary objectsForKeys:[NSArray arrayWithObject:@"myKey"]
notFoundMarker:@"defaultValue"]
objectAtIndex:0]
Вы не слышали это от меня 🙂
Ответ №2:
Что насчет этого?
NSString *value = [dictionary valueForKey:@"myKey"];
if (!value) value = @"defaultValue";
[myObject setMyString:value];
Комментарии:
1. Также можно сделать
[myObject setMyString:[dic...Key:@"myKey"] ?: @"defaultValue"];
2. Я знаю, что этот метод работает, но искал более однострочный MyObject.myString = [dictionary valueForKey@»MyKey»] ? [словарь valueForKey@»MyKey»]: @»»; Похоже, это не работает. Если для ключа есть значение, используйте значение для ключа, иначе сделайте @»»
3. Всегда можно создать категорию для NSArray, что-то вроде
objectForKey:(id)key withDefault:(id)defaultObject
. Это позволило бы выполнить операцию «один лайнер».
Ответ №3:
Используйте [NSNull null]
для общего случая и обработайте его, когда он будет возвращен.
В вашем вопросе вы не получили бы «нераспознанный селектор»; newString
будет установлено значение nil
(в отличие от [NSNull null]
, поэтому я подозреваю, что вы могли иметь в виду что-то другое — возможно, как установить значения по умолчанию для NSUserDefaults
?
Ответ №4:
Я сделал это с помощью простого расширения NSDictionary.
NSDictionary NSDictionaryExtensions.h
#import <Foundation/Foundation.h>
@interface NSDictionary (NSDictionaryExtensions)
- (id)objectForKey:(id)aKey defaultObject: (id) defObj;
@end
NSDictionary NSDictionaryExtensions.m
#import "NSDictionary NSDictionaryExtensions.h"
@implementation NSDictionary (NSDictionaryExtensions)
- (id)objectForKey:(id)aKey defaultObject: (id) defObj
{
id ret = [self objectForKey: aKey];
if ( ret == nil )
return defObj;
else
return ret;
}
@end
Затем я могу получить доступ следующим образом:
NSString* str = [dict objectForKey: @"a_key" defaultObject: @"default"];
Ответ №5:
попробуйте
if ( myObject == nil ) {
[myObject setMyString:@""];
}
или
if ( [dictionary valueForKey:@"myKey"] == nil ) {
[dictionary setObject:@"" forKey:@"myKey"];
}
Ответ №6:
Какое бы значение по умолчанию вы ни присвоили своей строке, оно не myObject.myString
вернет «нераспознанную ошибку селектора» — обычно свойство myString
либо существует, либо его нет («обычно», поскольку вы можете копаться в недрах среды выполнения Objective-C и играть в игры, но это редко (если вообще когда-либо) то, что вы хотитечто делать!)
Что вы пытаетесь сделать? Если ваша цель состоит в том, чтобы создать исключение myObject.myString
, если оно не установлено, вы можете сделать это в реализации свойства.
Например, valueForKey;
вернет nil
, если для данного ключа не установлено значение, поэтому вы можете проверить это в своем свойстве:
- (void) setMyString:(NSString *)value
{ myString = value;
}
- (NSString *) myString
{
if (myString == nil)
@throw [NSException exceptionWithName:@"UnrecognizedSelector" reason:@"No value set for myString" userInfo:nil];
return myString;
}
Примечания:
-
код, введенный на терминале, может содержать опечатки
-
код предполагает сборку мусора / ARC, если нет, вам нужно добавить соответствующее сохранение / копирование / выпуск
Но вы действительно хотите создать исключение? Обычно вы делаете это только в том случае, если строка должна быть установлена, а отсутствие этого является исключительным условием — вы не используете значения по умолчанию.
Ответ №7:
Согласно @Paul Lynch, вы должны проверить наличие [NSNull null], кроме nil. Также желательно проверить тип данных, который вы ищете:
- (id) objectForKey: (id) key withDefault: (id) defaultValue
{
id value = self[key];
if (value == nil || [value isEqual: [NSNull null]] || ![defaultValue isKindOfClass: [value class]])
{
value = defaultValue;
}
return value;
}
Ответ №8:
Вы можете вручную проверить наличие нулевых значений, как показано ниже, для разных типов:
extension NSDictionary {
func convertToString() -> String {
let jsonData = try! JSONSerialization.data(withJSONObject: self, options: JSONSerialization.WritingOptions.prettyPrinted) as NSData!
if jsonData == nil{
return "{}"
}else {
return String(data: jsonData as! Data, encoding: String.Encoding.utf8)!
}
}
func object_forKeyWithValidationForClass_Int(aKey: String) -> Int {
// CHECK FOR EMPTY
if(self.allKeys.count == 0) {
return Int()
}
// CHECK IF KEY EXIST
if let val = self.object(forKey: aKey) {
if((val as AnyObject).isEqual(NSNull())) {
return Int()
}
} else {
// KEY NOT FOUND
return Int()
}
// CHECK FOR NIL VALUE
let aValue : AnyObject = self.object(forKey: aKey)! as AnyObject
if aValue.isEqual(NSNull()) {
return Int()
}
else if(aValue.isKind(of: NSString.self)){
return Int((aValue as! NSString).intValue)
}
else {
if aValue is Int {
return self.object(forKey: aKey) as! Int
}
else{
return Int()
}
}
}
func object_forKeyWithValidationForClass_CGFloat(aKey: String) -> CGFloat {
// CHECK FOR EMPTY
if(self.allKeys.count == 0) {
return CGFloat()
}
// CHECK IF KEY EXIST
if let val = self.object(forKey: aKey) {
if((val as AnyObject).isEqual(NSNull())) {
return CGFloat()
}
} else {
// KEY NOT FOUND
return CGFloat()
}
// CHECK FOR NIL VALUE
let aValue : AnyObject = self.object(forKey: aKey)! as AnyObject
if aValue.isEqual(NSNull()) {
return CGFloat()
}
else {
if aValue is CGFloat {
return self.object(forKey: aKey) as! CGFloat
}
else{
return CGFloat()
}
}
}
func object_forKeyWithValidationForClass_String(aKey: String) -> String {
// CHECK FOR EMPTY
if(self.allKeys.count == 0) {
return String()
}
// CHECK IF KEY EXIST
if let val = self.object(forKey: aKey) {
if((val as AnyObject).isEqual(NSNull())) {
return String()
}
} else {
// KEY NOT FOUND
return String()
}
// CHECK FOR NIL VALUE
let aValue : AnyObject = self.object(forKey: aKey)! as AnyObject
if aValue.isEqual(NSNull()) {
return String()
}
else if(aValue.isKind(of: NSNumber.self)){
return String(format:"%f", (aValue as! NSNumber).doubleValue)
}
else {
if aValue is String {
return self.object(forKey: aKey) as! String
}
else{
return String()
}
}
}
func object_forKeyWithValidationForClass_StringInt(aKey: String) -> String {
// CHECK FOR EMPTY
if(self.allKeys.count == 0) {
return String()
}
// CHECK IF KEY EXIST
if let val = self.object(forKey: aKey) {
if((val as AnyObject).isEqual(NSNull())) {
return String()
}
} else {
// KEY NOT FOUND
return String()
}
// CHECK FOR NIL VALUE
let aValue : AnyObject = self.object(forKey: aKey)! as AnyObject
if aValue.isEqual(NSNull()) {
return String()
}
else if(aValue.isKind(of: NSNumber.self)){
return String(format:"%d", (aValue as! NSNumber).int64Value)
}
else {
if aValue is String {
return self.object(forKey: aKey) as! String
}
else{
return String()
}
}
}
func object_forKeyWithValidationForClass_Bool(aKey: String) -> Bool {
// CHECK FOR EMPTY
if(self.allKeys.count == 0) {
return Bool()
}
// CHECK IF KEY EXIST
if let val = self.object(forKey: aKey) {
if((val as AnyObject).isEqual(NSNull())) {
return Bool()
}
} else {
// KEY NOT FOUND
return Bool()
}
// CHECK FOR NIL VALUE
let aValue : AnyObject = self.object(forKey: aKey)! as AnyObject
if aValue.isEqual(NSNull()) {
return Bool()
}
else {
if aValue is Bool {
return self.object(forKey: aKey) as! Bool
}
else{
return Bool()
}
}
}
func object_forKeyWithValidationForClass_NSArray(aKey: String) -> NSArray {
// CHECK FOR EMPTY
if(self.allKeys.count == 0) {
return NSArray()
}
// CHECK IF KEY EXIST
if let val = self.object(forKey: aKey) {
if((val as AnyObject).isEqual(NSNull())) {
return NSArray()
}
} else {
// KEY NOT FOUND
return NSArray()
}
// CHECK FOR NIL VALUE
let aValue : AnyObject = self.object(forKey: aKey)! as AnyObject
if aValue.isEqual(NSNull()) {
return NSArray()
}
else {
if aValue is NSArray {
return self.object(forKey: aKey) as! NSArray
}
else{
return NSArray()
}
}
}
func object_forKeyWithValidationForClass_NSMutableArray(aKey: String) -> NSMutableArray {
// CHECK FOR EMPTY
if(self.allKeys.count == 0) {
return NSMutableArray()
}
// CHECK IF KEY EXIST
if let val = self.object(forKey: aKey) {
if((val as AnyObject).isEqual(NSNull())) {
return NSMutableArray()
}
} else {
// KEY NOT FOUND
return NSMutableArray()
}
// CHECK FOR NIL VALUE
let aValue : AnyObject = self.object(forKey: aKey)! as AnyObject
if aValue.isEqual(NSNull()) {
return NSMutableArray()
}
else {
if aValue is NSMutableArray {
return self.object(forKey: aKey) as! NSMutableArray
}
else{
return NSMutableArray()
}
}
}
func object_forKeyWithValidationForClass_NSDictionary(aKey: String) -> NSDictionary {
// CHECK FOR EMPTY
if(self.allKeys.count == 0) {
return NSDictionary()
}
// CHECK IF KEY EXIST
if let val = self.object(forKey: aKey) {
if((val as AnyObject).isEqual(NSNull())) {
return NSDictionary()
}
} else {
// KEY NOT FOUND
return NSDictionary()
}
// CHECK FOR NIL VALUE
let aValue : AnyObject = self.object(forKey: aKey)! as AnyObject
if aValue.isEqual(NSNull()) {
return NSDictionary()
}
else {
if aValue is NSDictionary {
return self.object(forKey: aKey) as! NSDictionary
}
else{
return NSDictionary()
}
}
}
func object_forKeyWithValidationForClass_NSMutableDictionary(aKey: String) -> NSMutableDictionary {
// CHECK FOR EMPTY
if(self.allKeys.count == 0) {
return NSMutableDictionary()
}
// CHECK IF KEY EXIST
if let val = self.object(forKey: aKey) {
if((val as AnyObject).isEqual(NSNull())) {
return NSMutableDictionary()
}
} else {
// KEY NOT FOUND
return NSMutableDictionary()
}
// CHECK FOR NIL VALUE
let aValue : AnyObject = self.object(forKey: aKey)! as AnyObject
if aValue.isEqual(NSNull()) {
return NSMutableDictionary()
}
else {
if aValue is NSMutableDictionary {
return self.object(forKey: aKey) as! NSMutableDictionary
}
else{
return NSMutableDictionary()
}
}
}
}