如何在Objective-C中创建内联条件赋值?
My如何在Objective-C中创建内联条件赋值?,objective-c,if-statement,syntax,conditional-statements,Objective C,If Statement,Syntax,Conditional Statements,MyPet类有两个属性:BOOLisHungry和NSNumber*age。 我想把宠物myPet的属性放入NSMutableDictionary*myMap 这是我的代码是Java。我正试图用Objective-C写一个等价物 myMap.put("isHungry", myPet == null ? null : myPet.isHungry); myMap.put("age", myPet == null ? null : myPet.age);
Pet
类有两个属性:BOOLisHungry
和NSNumber*age
。
我想把宠物myPet的属性放入NSMutableDictionary*myMap
这是我的代码是Java。我正试图用Objective-C写一个等价物
myMap.put("isHungry", myPet == null ? null : myPet.isHungry);
myMap.put("age", myPet == null ? null : myPet.age);
这是我当前的Objective-C版本:
[myMap addEntriesFromDictionary:@{
@"isHungry" : myPet ? myPet.isHungry : (NSInteger)[NSNull null],
@"age" : myPet ? myPet.age : [NSNull null],
}];
第二行的错误如下:
Incompatible operand types ('int' and 'NSNull * _Nonnull')
当我添加(NSInteger)时,编译器停止抱怨第一行。
如果我在第二行输入相同的代码,错误会消失,但编译器会再次抱怨第一行:
Collection element of type 'long' is not an Objective-C object
我是Obj-C的一个疯子,我完全迷路了。我还想知道Obj-C的最佳实践。因为您有一个带有
@property BOOL-isHungry的宠物类代码>和@property NSNumber*年龄
而您的myMap
是NSMutableDictionary
您的解决方案应该是这样的
Pet *myPet = [[Pet alloc] init];
myPet.age = @(2);
myPet.isHungry = YES;
NSMutableDictionary *myMap = [[NSMutableDictionary alloc] init];
if (myPet!=nil) {
[myMap addEntriesFromDictionary:@{
@"isHungry" : @(myPet.isHungry),
@"age" : myPet.age
}];
}
// with this you store only the values of Pet
NSLog(@"%@",myMap.description);
// but that goes even easier..
NSMutableDictionary *myDict = [NSMutableDictionary new];
myDict[@"Pet1"] = myPet;
NSLog(@"%@",myDict.description);
Pet *petInDict = myDict[@"Pet"];
NSLog(@"age=%@ isHungry=%@",petInDict.age, (petInDict.isHungry ? @"YES":@"NO") );
// should be age=(null) isHungry=NO
// because we stored with key myDict[@"Pet1"] and not myDict[@"Pet"]
// ok lets take the key we used
Pet *pet1 = myDict[@"Pet1"];
NSLog(@"age=%@ isHungry=%@",pet1.age, (pet1.isHungry ? @"YES":@"NO") );
由于存在非NSObject子类的泛型数据类型,因此如果不将它们存储到对象中,就无法将它们存储在字典中
@(yournumber) // converts to NSNumber
@(YES) // converts to NSNumber = 1
@(NO) // converts to NSNumber = 0
@[@(1),@(2),@(3)] // converts to an NSArray with 3 NSNumbers
@{} // this one you know allready, its a NSDictionary
@"hello" // well NSString of course
@selector(name:) // thats a pointer to a method with name:, of type SEL
...
@{@"key1":@YES, @"key2":@NO}
// it is possible to convert BOOL directly
你也可以用这种方式开始,但你会发现它看起来很奇怪
NSMutableDictionary*syntaxsugar=[({“isHungry”:(myPet.isHungry),“age”:myPet.age})mutableCopy]代码>
mutableCopy
生成前导数据类型NSDictionary的可变副本。目标C中的字典只能存储对象,也只能存储现有对象
通过写入@(myPet.isHungry),可以将布尔值或算术值(如myPet.isHungry)转换为NSNumber对象。您可以通过写入[NSNull]来创建一个可以代表nil的对象
当您试图从字典中提取一个值时,会得到一个object或nil。您可以通过检查来检查对象是否表示nil
if (value == nil || value == [NSNull null])
第二个比较有效,因为始终只有一个NSNull对象
如果您知道该值是NSNumber对象,则可以使用布尔值或整数值等来提取该值。您的isHungry
是布尔值。数组和字典只能存储对象。但是BOOL
和NSInteger
是基本类型,而不是对象(这就是为什么会出现错误)。但您可以将其转换为对象(NSNumber
),并将其添加到字典中
您可以通过两种方式将BOOL
值转换为NSNumber
,方法是在值前面添加@
,或使用numberwhithbool:
例如:
NSNumber *isHungry = @(myPet.isHungry); // OR
NSNumber *isHungry = [NSNumber numberWithBool:myPet.isHungry];
您可以内联执行此操作,这样您的代码看起来(和工作方式)如下:
当您从字典中检索数据时,您将获得以前存储的NSNumber。但是如果需要的话,你可以把它转换回BOOL
// getting BOOL back
NSNumber *isHungryObj = myMap[@"isHungry"]; // it must be NSNumber not NSNull!
BOOL isHungry = isHungry.boolValue;
但在上述情况下,您必须确保存储的对象实际上是NSNumber
,而不是NSNull
。因为在NSNull
的情况下,应用程序将崩溃,因为NSNull
不是NSNumber
并且不响应boolValue
。
为了避免这种情况,您可以:
- 始终必须根据
NSNull
检查返回的对象(这不是最佳解决方案,在字典中的同一个键下存储两种不同类型的对象也不是最佳做法)
- 根据您的需要,在没有myPet的情况下,最好存储一些默认值,而不是
NSNull
。例如为iHungry设置@NO
,为age设置@0
- 或者你可以在添加值之前检查myPet是否存在,如果它不存在,就不要向myMap添加任何内容。在这种情况下,如果您没有向myMap添加任何内容,那么调用
myMap[@“isHungry”]
将返回nil
。
它是Objective-C中null
的另一个变体。检查nil
比NSNull
更容易,即使您向nil
发送一些消息,也不会发生任何不好的事情。在Objective-C中,允许向nil
发送消息。不能像使用NSNull
那样将nil
存储在字典中,但可以将对象与nil
进行比较
第三个选项的示例代码:
// adding to a dictionary, does the same thing as your code
if (myPet != nil) // OR if (myPet)
{
myMap[@"isHungry"] = @(myPet.isHungry);
myMap[@"age"] = myPet.age;
}
// retrieving
if (myMap[@"age"])
{
// number exists, you can do something with it
}
由于nil
可以毫无问题地向其发送消息,因此有时您甚至不需要检查nil
,例如在这种情况下:
if ([myMap[@"age"] integerValue] == 5) // returns YES if it's 5 and NO in any other case even if @"age" wasn't set and is nil
希望这有帮助。有很多教程。。这里有一个。。什么是我的地图?一本易变字典?或者您想定义一个类?@OlSen myMap是NSMutableDictionaryo您有一个属性为BOOL isHungry的类宠物;和财产编号*年龄@奥尔森:是的,没错。
if ([myMap[@"age"] integerValue] == 5) // returns YES if it's 5 and NO in any other case even if @"age" wasn't set and is nil