如何检测字典是否为空或 null
How to detect if a dictionary is empty or null
我收到一个 JSON 字符串,我需要对其进行迭代以检索一些 object 值。
这是结构
-meta
-objects
|_cabdriver
|_employee
|client
objects树下有objects,还有child个节点,比如cabdriver和client。 child 节点 cabdriver 还有另一个 child 节点称为 employee。
这是我迭代它的方式:
NSArray *messageArray = [json objectForKey:@"objects"];
historialServicios = [[NSMutableArray alloc]init];
// Parse and loop through the JSON
for (dictionary in messageArray) {
//datos de nivel objects
NSString * date = [dictionary objectForKey:@"date"];
NSString * origin = [dictionary objectForKey:@"origin"];
NSString * destiny = [dictionary objectForKey:@"destiny"];
NSString * rate = [dictionary objectForKey:@"service_rate"];
NSString * state = [dictionary objectForKey:@"state"];
NSString * time_service = [dictionary objectForKey:@"time_service"];
NSString * id_service = [dictionary objectForKey:@"id"];
//datos de nivel cliente
NSDictionary *level2Dict = [dictionary objectForKey:@"client"];
NSString *client_id = [level2Dict objectForKey:@"id"];
//datos de nivel cabdriver
NSDictionary *cabdriverLevelDict=[dictionary objectForKey:@"cabdriver"];
//datos de nivel employee
NSDictionary *employeeLevelDict = [cabdriverLevelDict objectForKey:@"employee"];
//datos del employee
NSString *driverName = [employeeLevelDict objectForKey:@"name"];
NSString *driverLastname = [employeeLevelDict objectForKey:@"lastname"];
NSString *driverPhone = [employeeLevelDict objectForKey:@"phone"];
NSString *driverId = [employeeLevelDict objectForKey:@"id"];
[historialServicios addObject:@{
@"time_service": time_service,
@"id_service": id_service,
@"rate": rate,
@"destiny": destiny,
@"state": state,
@"origin": origin,
@"client_id":client_id,
@"date": date,
@"driverName":driverName,
@"driverLastname": driverLastname,
@"driverPhone": driverPhone,
@"driverId": driverId
}];
NSLog(@"DESPUES DE ANADIR OBJETOS");
NSLog(@"OBJETO ANADIDO==>TIME SERVICE = %@, ID SERVICE=%@, SERVICE RATE=%@,SERVICE DATE=%@,DESTINY=%@, STATE =%@,CLIENT ID=%@, ORIGIN=%@,DRIVER NAME=%@, DRIVER LASTNAME=%@,DRIVER PHONE=%@, DRIVER ID=%@",time_service,id_service,rate,date,destiny,state,client_id,origin,driverName,driverLastname,driverPhone,driverId);
//insertamos objetos en diccionario historialServicios
}
如果 object 有所有节点,一切正常,但有时,节点出租车司机是空的,没有雇员 child 节点。如果是这种情况,我会抛出异常并且应用程序崩溃。
如何判断节点员工不存在,避免出现异常?
谢谢。
检查字典的计数
if ([cabdriverLevelDict count] == 0) {
NSLog("empty");
}
else{
// Do your stuff !!
}
你可以试试
NSDictionary *employeeLevelDict = [cabdriverLevelDict objectForKey:@"employee"];
if (employeeLevelDict.count != 0)
{
// do something if dict is not empty
}
else
{
}];
在这里试试这个:
if( cabdriverLevelDict.allkeys.count ){
// Do something with the dict
} else {
// dict is empty
}
if (![cabdriverLevelDict isKindOfClass:[NSNull class]] ){
//do something
}
试试这个
您可以声明一个类别来处理注入到您的 json 中的 [NSNull null]
值。
@interface NSDictionary (NilNull)
- (id)optionalObjectForKey:(id)key;
- (id)optionalObjectForKey:(id)key defaultValue:(id)defaultValue;
@end
@implementation NSDictionary (NilNull)
- (id)optionalObjectForKey:(id)key {
return [self optionalObjectForKey:key defaultValue:nil];
]
- (id)optionalObjectForKey:(id)key defaultValue:(id)defaultValue {
id obj = [self objectForKey:key];
return (obj == [NSNull null] || !obj) ? defaultValue : obj;
}
@end
然后改用它:
NSDictionary *cabdriverLevelDict = [dictionary optionalObjectForKey:@"cabdriver"];
NSDictionary *employeeLevelDict = [cabdriverLevelDict optionalObjectForKey:@"employee"];
您尚未发布异常的内容,但从外观上看,它可能与尝试向新词典添加 nil
值有关。
然后对所有生成对象的数据查找使用默认值 [NSNull null]
,您将使用这些对象构建最终字典。完整的查找源现在是这样的:
NSString * date = [dictionary optionalObjectForKey:@"date" defaultValue:[NSNull null]];
NSString * origin = [dictionary optionalObjectForKey:@"origin" defaultValue:[NSNull null]];
NSString * destiny = [dictionary optionalObjectForKey:@"destiny" defaultValue:[NSNull null]];
NSString * rate = [dictionary optionalObjectForKey:@"service_rate" defaultValue:[NSNull null]];
NSString * state = [dictionary optionalObjectForKey:@"state" defaultValue:[NSNull null]];
NSString * time_service = [dictionary optionalObjectForKey:@"time_service" defaultValue:[NSNull null]];
NSString * id_service = [dictionary optionalObjectForKey:@"id" defaultValue:[NSNull null]];
//datos de nivel cliente
NSDictionary *level2Dict = [dictionary optionalObjectForKey:@"client" defaultValue:[NSDictionary dictionary]];
NSString *client_id = [level2Dict optionalObjectForKey:@"id" defaultValue:[NSNull null]];
//datos de nivel cabdriver
NSDictionary *cabdriverLevelDict=[dictionary optionalObjectForKey:@"cabdriver" defaultValue:[NSDictionary dictionary]];
//datos de nivel employee
NSDictionary *employeeLevelDict = [cabdriverLevelDict optionalObjectForKey:@"employee" defaultValue:[NSDictionary dictionary]];
//datos del employee
NSString *driverName = [employeeLevelDict optionalObjectForKey:@"name" defaultValue:[NSNull null]];
NSString *driverLastname = [employeeLevelDict optionalObjectForKey:@"lastname" defaultValue:[NSNull null]];
NSString *driverPhone = [employeeLevelDict optionalObjectForKey:@"phone" defaultValue:[NSNull null]];
NSString *driverId = [employeeLevelDict optionalObjectForKey:@"id" defaultValue:[NSNull null]];
基本上,您需要检查获得的每一个结果。如果您不这样做,您的应用程序就会受到攻击,一次攻击可能会让黑客进入用户的设备并造成无限的损害。在你期望字典的地方,你可能会得到 nil,你可能会得到 null,你可能会得到一个数字或一个字符串,任何东西。这很简单。
NSDictionary* dict = ...;
if (! [dict isKindOfClass:[NSDictionary class]]) dict = nil;
在Objective-C中,nil对象是相当安全的。例如,您可以使用 objectForKey [@"employee"],结果将是 nil。无论如何你都可能收到零。
只检查 [NSNull null] 是没有意义的,因为服务器给你的任何其他结果都会让你的应用程序崩溃。只需检查您实际期望的内容。丢弃不正确的数据很好,毕竟 JSON 反序列化器将丢弃所有数据,如果只有一个字节的数据是错误的。
有时您需要多加注意,因为服务器行为不当而您必须应对。例如,服务器应该 return 字典数组可能只给你一个字典,如果只有一个,所以你会检查例如
NSArray* arrayOfDicts = ...;
if ([arrayOfDicts isKindOfClass:[NSDictionary class]] arrayOfDicts = @[arrayOfDicts];
else if (! [arrayOfDicts isKindOfClass:[NSArray class]] arrayOfDicts = nil;
正如其他人指出的那样,如果传递到字典中的任何对象为 nil,则会引发异常,使您的应用程序崩溃。通过执行以下操作:
[historialServicios addObject:@{
@"time_service": time_service,
@"id_service": id_service,
@"rate": rate,
@"destiny": destiny,
@"state": state,
@"origin": origin,
@"client_id":client_id,
@"date": date,
@"driverName":driverName,
@"driverLastname": driverLastname,
@"driverPhone": driverPhone,
@"driverId": driverId
}];
您依赖所有这些对象(例如 time_service、id_service 等)不为零。正如您所指出的,它们可以为零,因此您需要有一种方法来检查您所做的每个对象。我建议使用 NSMutableDictionary,制作一个类别方法,如果它们都不为零,则只添加 key/value 对:
@implementation NSMutableDictionary (Util)
-(void)setObjectOrRemoveIfNil:(id)anObject forKey:(id<NSCopying>)aKey
{
if (anObject == nil)
{
[self removeObjectForKey:aKey];
}
else
{
[self setObject:anObject forKey:aKey];
}
}
@end
然后像这样整理你的字典:
NSMutableDictionary* values = [NSMutableDictionary dictionary];
[values setObjectOrRemoveIfNil:time_service forKey:@"time_service"];
[values setObjectOrRemoveIfNil:id_service forKey:@"id_service"];
//Keep going with the rest of your values.
最后我们像您一样使用该字典:
[historialServicios addObject:values];
我收到一个 JSON 字符串,我需要对其进行迭代以检索一些 object 值。 这是结构
-meta -objects |_cabdriver |_employee |client
objects树下有objects,还有child个节点,比如cabdriver和client。 child 节点 cabdriver 还有另一个 child 节点称为 employee。
这是我迭代它的方式:
NSArray *messageArray = [json objectForKey:@"objects"];
historialServicios = [[NSMutableArray alloc]init];
// Parse and loop through the JSON
for (dictionary in messageArray) {
//datos de nivel objects
NSString * date = [dictionary objectForKey:@"date"];
NSString * origin = [dictionary objectForKey:@"origin"];
NSString * destiny = [dictionary objectForKey:@"destiny"];
NSString * rate = [dictionary objectForKey:@"service_rate"];
NSString * state = [dictionary objectForKey:@"state"];
NSString * time_service = [dictionary objectForKey:@"time_service"];
NSString * id_service = [dictionary objectForKey:@"id"];
//datos de nivel cliente
NSDictionary *level2Dict = [dictionary objectForKey:@"client"];
NSString *client_id = [level2Dict objectForKey:@"id"];
//datos de nivel cabdriver
NSDictionary *cabdriverLevelDict=[dictionary objectForKey:@"cabdriver"];
//datos de nivel employee
NSDictionary *employeeLevelDict = [cabdriverLevelDict objectForKey:@"employee"];
//datos del employee
NSString *driverName = [employeeLevelDict objectForKey:@"name"];
NSString *driverLastname = [employeeLevelDict objectForKey:@"lastname"];
NSString *driverPhone = [employeeLevelDict objectForKey:@"phone"];
NSString *driverId = [employeeLevelDict objectForKey:@"id"];
[historialServicios addObject:@{
@"time_service": time_service,
@"id_service": id_service,
@"rate": rate,
@"destiny": destiny,
@"state": state,
@"origin": origin,
@"client_id":client_id,
@"date": date,
@"driverName":driverName,
@"driverLastname": driverLastname,
@"driverPhone": driverPhone,
@"driverId": driverId
}];
NSLog(@"DESPUES DE ANADIR OBJETOS");
NSLog(@"OBJETO ANADIDO==>TIME SERVICE = %@, ID SERVICE=%@, SERVICE RATE=%@,SERVICE DATE=%@,DESTINY=%@, STATE =%@,CLIENT ID=%@, ORIGIN=%@,DRIVER NAME=%@, DRIVER LASTNAME=%@,DRIVER PHONE=%@, DRIVER ID=%@",time_service,id_service,rate,date,destiny,state,client_id,origin,driverName,driverLastname,driverPhone,driverId);
//insertamos objetos en diccionario historialServicios
}
如果 object 有所有节点,一切正常,但有时,节点出租车司机是空的,没有雇员 child 节点。如果是这种情况,我会抛出异常并且应用程序崩溃。
如何判断节点员工不存在,避免出现异常?
谢谢。
检查字典的计数
if ([cabdriverLevelDict count] == 0) {
NSLog("empty");
}
else{
// Do your stuff !!
}
你可以试试
NSDictionary *employeeLevelDict = [cabdriverLevelDict objectForKey:@"employee"];
if (employeeLevelDict.count != 0)
{
// do something if dict is not empty
}
else
{
}];
在这里试试这个:
if( cabdriverLevelDict.allkeys.count ){
// Do something with the dict
} else {
// dict is empty
}
if (![cabdriverLevelDict isKindOfClass:[NSNull class]] ){
//do something
}
试试这个
您可以声明一个类别来处理注入到您的 json 中的 [NSNull null]
值。
@interface NSDictionary (NilNull)
- (id)optionalObjectForKey:(id)key;
- (id)optionalObjectForKey:(id)key defaultValue:(id)defaultValue;
@end
@implementation NSDictionary (NilNull)
- (id)optionalObjectForKey:(id)key {
return [self optionalObjectForKey:key defaultValue:nil];
]
- (id)optionalObjectForKey:(id)key defaultValue:(id)defaultValue {
id obj = [self objectForKey:key];
return (obj == [NSNull null] || !obj) ? defaultValue : obj;
}
@end
然后改用它:
NSDictionary *cabdriverLevelDict = [dictionary optionalObjectForKey:@"cabdriver"];
NSDictionary *employeeLevelDict = [cabdriverLevelDict optionalObjectForKey:@"employee"];
您尚未发布异常的内容,但从外观上看,它可能与尝试向新词典添加 nil
值有关。
然后对所有生成对象的数据查找使用默认值 [NSNull null]
,您将使用这些对象构建最终字典。完整的查找源现在是这样的:
NSString * date = [dictionary optionalObjectForKey:@"date" defaultValue:[NSNull null]];
NSString * origin = [dictionary optionalObjectForKey:@"origin" defaultValue:[NSNull null]];
NSString * destiny = [dictionary optionalObjectForKey:@"destiny" defaultValue:[NSNull null]];
NSString * rate = [dictionary optionalObjectForKey:@"service_rate" defaultValue:[NSNull null]];
NSString * state = [dictionary optionalObjectForKey:@"state" defaultValue:[NSNull null]];
NSString * time_service = [dictionary optionalObjectForKey:@"time_service" defaultValue:[NSNull null]];
NSString * id_service = [dictionary optionalObjectForKey:@"id" defaultValue:[NSNull null]];
//datos de nivel cliente
NSDictionary *level2Dict = [dictionary optionalObjectForKey:@"client" defaultValue:[NSDictionary dictionary]];
NSString *client_id = [level2Dict optionalObjectForKey:@"id" defaultValue:[NSNull null]];
//datos de nivel cabdriver
NSDictionary *cabdriverLevelDict=[dictionary optionalObjectForKey:@"cabdriver" defaultValue:[NSDictionary dictionary]];
//datos de nivel employee
NSDictionary *employeeLevelDict = [cabdriverLevelDict optionalObjectForKey:@"employee" defaultValue:[NSDictionary dictionary]];
//datos del employee
NSString *driverName = [employeeLevelDict optionalObjectForKey:@"name" defaultValue:[NSNull null]];
NSString *driverLastname = [employeeLevelDict optionalObjectForKey:@"lastname" defaultValue:[NSNull null]];
NSString *driverPhone = [employeeLevelDict optionalObjectForKey:@"phone" defaultValue:[NSNull null]];
NSString *driverId = [employeeLevelDict optionalObjectForKey:@"id" defaultValue:[NSNull null]];
基本上,您需要检查获得的每一个结果。如果您不这样做,您的应用程序就会受到攻击,一次攻击可能会让黑客进入用户的设备并造成无限的损害。在你期望字典的地方,你可能会得到 nil,你可能会得到 null,你可能会得到一个数字或一个字符串,任何东西。这很简单。
NSDictionary* dict = ...;
if (! [dict isKindOfClass:[NSDictionary class]]) dict = nil;
在Objective-C中,nil对象是相当安全的。例如,您可以使用 objectForKey [@"employee"],结果将是 nil。无论如何你都可能收到零。
只检查 [NSNull null] 是没有意义的,因为服务器给你的任何其他结果都会让你的应用程序崩溃。只需检查您实际期望的内容。丢弃不正确的数据很好,毕竟 JSON 反序列化器将丢弃所有数据,如果只有一个字节的数据是错误的。
有时您需要多加注意,因为服务器行为不当而您必须应对。例如,服务器应该 return 字典数组可能只给你一个字典,如果只有一个,所以你会检查例如
NSArray* arrayOfDicts = ...;
if ([arrayOfDicts isKindOfClass:[NSDictionary class]] arrayOfDicts = @[arrayOfDicts];
else if (! [arrayOfDicts isKindOfClass:[NSArray class]] arrayOfDicts = nil;
正如其他人指出的那样,如果传递到字典中的任何对象为 nil,则会引发异常,使您的应用程序崩溃。通过执行以下操作:
[historialServicios addObject:@{
@"time_service": time_service,
@"id_service": id_service,
@"rate": rate,
@"destiny": destiny,
@"state": state,
@"origin": origin,
@"client_id":client_id,
@"date": date,
@"driverName":driverName,
@"driverLastname": driverLastname,
@"driverPhone": driverPhone,
@"driverId": driverId
}];
您依赖所有这些对象(例如 time_service、id_service 等)不为零。正如您所指出的,它们可以为零,因此您需要有一种方法来检查您所做的每个对象。我建议使用 NSMutableDictionary,制作一个类别方法,如果它们都不为零,则只添加 key/value 对:
@implementation NSMutableDictionary (Util)
-(void)setObjectOrRemoveIfNil:(id)anObject forKey:(id<NSCopying>)aKey
{
if (anObject == nil)
{
[self removeObjectForKey:aKey];
}
else
{
[self setObject:anObject forKey:aKey];
}
}
@end
然后像这样整理你的字典:
NSMutableDictionary* values = [NSMutableDictionary dictionary];
[values setObjectOrRemoveIfNil:time_service forKey:@"time_service"];
[values setObjectOrRemoveIfNil:id_service forKey:@"id_service"];
//Keep going with the rest of your values.
最后我们像您一样使用该字典:
[historialServicios addObject:values];