Ios 即使使用if/else语句也会导致崩溃的空值?

Ios 即使使用if/else语句也会导致崩溃的空值?,ios,objective-c,Ios,Objective C,我遇到了最奇怪的问题。我正在使用下面的代码显示登录用户的个人资料照片(我正在从Drupal数据库的一个字段中检索图像) .m //USER PHOTO NSDictionary *user = [[DIOSSession sharedSession] user]; NSString *secondLink = user[@"field_photo_path"][@"und"][0][@"safe_value"]; NSLog(@"This is second link

我遇到了最奇怪的问题。我正在使用下面的代码显示登录用户的个人资料照片(我正在从Drupal数据库的一个字段中检索图像)

.m

//USER PHOTO

    NSDictionary *user = [[DIOSSession sharedSession] user];
    NSString *secondLink = user[@"field_photo_path"][@"und"][0][@"safe_value"];

    NSLog(@"This is second link %@", secondLink);

 if([secondLink length]>0) {


    NSString *ImageURL = secondLink;
   NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];
 //   self.imageView.image = [UIImage imageWithData:imageData];
   self.imageView.image = [[UIImage alloc] initWithData:imageData];

  } else {

   NSString *ImageURL = @"http://url.com/default.png";
    NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];
   self.imageView.image = [UIImage imageWithData:imageData];
}
当然,如果secondLink为空(或为空,例如没有上传照片),我会收到以下错误:

***由于未捕获异常“NSInvalidArgumentException”而终止应用程序,原因:'-[\u NSArray0 ObjectForkeydSubscript::发送到实例的选择器无法识别 0x14f602fe0'

我以为我用if/else语句解决了这个问题,但显然没有。我怎样才能解决这个问题

干杯

NSString *secondLink = user[@"field_photo_path"][@"und"][0][@"safe_value"];
在深入阅读之前,您需要验证用户词典是否有效

if (user[@"field_photo_path"]) {

     // you can look for [@"und"] here
     // providing it is a dictionary and not an array
     if([user[@"field_photo_path"] isKindOfClass:[NSDictionary class]]){
         if (user[@"field_photo_path"][@"und"]) {
            // etc
         }
    }
}
通过将
User
类建模为
NSObject
子类,并在该类中包含安全解析此数据的方法,可以减少此嵌套代码,从而只允许在一个位置编写此验证代码

编辑 如评论中所述:


如果
user[@“field\u photo\u path”[@“und”]
中的数据是
NSDictionary
而不是
NSArray
中的数据,则无法使用
[0]
访问该数据,并将导致崩溃。您可以使用索引(
array[0]
array[1]
等)和带有键(
dict[@“name”]
dict[@“und”]
等)的
NSDictionary

解决方案是检查您的钥匙

//用户照片

NSDictionary *user = [[DIOSSession sharedSession] user];
if (user[@"field_photo_path"]) {


    if ([user[@"field_photo_path"] isKindOfClass:[NSDictionary class]]) {

        if (user[@"field_photo_path"][@"und"]) {
            if ([user[@"field_photo_path"][@"und"]isKindOfClass:[NSArray class]]) {

                if ([user[@"field_photo_path"][@"und"] count]>0) {

                    if (user[@"field_photo_path"][@"und"][0][@"safe_value"]) {

                        if ([user[@"field_photo_path"][@"und"][0][@"safe_value"] isKindOfClass:[NSDictionary class]]){

                            NSString *secondLink = user[@"field_photo_path"][@"und"][0][@"safe_value"];

                            NSLog(@"This is second link %@", secondLink);

                            if([secondLink length]>0) {


                                NSString *ImageURL = secondLink;
                                NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];
                                //   self.imageView.image = [UIImage imageWithData:imageData];
                                self.imageView.image = [[UIImage alloc] initWithData:imageData];

                            } else {

                                NSString *ImageURL = @"http://url.com/default.png";
                                NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];
                                self.imageView.image = [UIImage imageWithData:imageData];
                            }
                        }


                    }
                }

            }
        }

    }
}
您也可以使用try-catch-block来避免崩溃

@try {
    //USER PHOTO

    NSDictionary *user = [[DIOSSession sharedSession] user];
    NSString *secondLink = user[@"field_photo_path"][@"und"][0][@"safe_value"];

    NSLog(@"This is second link %@", secondLink);

    if([secondLink length]>0) {


        NSString *ImageURL = secondLink;
        NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];
        //   self.imageView.image = [UIImage imageWithData:imageData];
        self.imageView.image = [[UIImage alloc] initWithData:imageData];

    } else {

        NSString *ImageURL = @"http://url.com/default.png";
        NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];
        self.imageView.image = [UIImage imageWithData:imageData];
    }
}
@catch (NSException *exception) {
    //Handle expecption
}
@finally {

}

撞车在哪一条线上?根据消息,它似乎位于
NSString*secondLink=…
行上,并且您正在使用的一个中间值(就像字典一样)实际上是一个数组。@dan NSString*secondLink=user[@“field\u photo\u path”][@“und”][0][@“safe\u value”];-这是崩溃的行,但只有当field\u photo\u path为空时才会崩溃。当它是空的时候,我需要它不要崩溃,哈哈。如果它是空的,它就不会崩溃——那里的某些东西包含了你意想不到的东西。我建议对您访问的所有内容使用变量,这样您就有机会调试它。在它崩溃的行上设置一个断点,然后检查
user
字典,查看数据是否在您期望的位置。其中一个下标可能不是你所期望的。好吧,我很困惑,哈哈。对不起,我是个新手。我不明白这段代码如何防止错误发生?字段返回良好,并且错误仅在数据不存在时发生?是的,错误发生在访问不存在的对象或错误类型的对象时。请尝试我的答案。我已尝试更正代码,它可能会解决问题problem@TarunSeerayour代码不足以防止崩溃。如果用户[@“field_photo_path”][@“und”]中的数据是NSDictionary而不是NSArray,则无法使用[0]访问该数据,并将导致崩溃。您使用索引(数组[0]、数组[1]等)访问NSArray,并使用带有键(dict[@“name”]dict[@“und”]等)的NSDictionary访问NSArray。您提供的捕获有效-这不是处理它的最佳方法吗?因为我喜欢它haha@Brittany这不是最好的处理方法。您的传入数据未进行解析,因为它返回了您不期望的内容。用try/catch包装并不能解决问题;您忽略了它。删除了您的第一个代码块,仍然发生错误:/n没问题。您可以打印您的NSDictionary*用户并共享该值,以便我们可以检查到底有哪些数据,还可以尝试@try块代码,您可能试图从数组中获取键值,但这是不可能的。我已经对我的答案进行了评论-仅检查是否存在/计数是不够的。您需要检查对象的类型请共享字典数据,代码不足以检查问题,共享NSDictionary*user=[[DIOSSession sharedSession]user]用户数据其中有什么值