在 iOS 中使用数组解析 JSON 时出错

Posted

技术标签:

【中文标题】在 iOS 中使用数组解析 JSON 时出错【英文标题】:Getting error in JSON parsing with array in iOS 【发布时间】:2015-06-16 06:10:56 【问题描述】:

我是 iPhone 的新手,基本上在我的应用程序中我正在解析 JSON 模型,需要将其保存在我的自定义实体类中。

JSON 模型:


    "Products": [
        
            "Pcs": [
                
                    "product_id": 2,
                    "product_name": "MyProduct",
                    "category": 
                        "Clamshells": [
                            
                                "product_category_id": 11,
                                "product_category_name": "MyProductCategory",
                                "Sub_category": [
                                    
                                        "sub_category_id": 21,
                                        "sub_category_name": "MyProductSubCategory"
                                    
                                ]
                            
                        ],
                        "Detachables": [
                            
                                "product_category_id": 12,
                                "product_category_name": "MyProductCatrgory1",
                                "Sub_category": [
                                    
                                        "sub_category_id": 31,
                                        "sub_category_name": "MyProductSubCategory1"
                                    
                                ]
                            
                        ],
                        "Convertibles": [
                            
                                "product_category_id": 13,
                                "product_category_name": "MyProductCatrgory2",
                                "Sub_category": [
                                    
                                        "sub_category_id": 41,
                                        "sub_category_name": "MyProductSubCategory2"
                                    
                                ]
                            
                        ]
                    
                
            ]
        
    ]

我创建了三个实体类,例如:

PCs.h:

#import <Foundation/Foundation.h>
#import "MyProductCategory.h"

@interface PCs : NSObject

@property (nonatomic, retain) NSString *productTitle;
@property (nonatomic, retain) NSString *productId;
@property (nonatomic, retain) MyProductCategory *myProductCategory;

@end

MyProductCategory.h:

#import <Foundation/Foundation.h>
#import "Clamshell.h"

@interface MyProductCategory : NSObject

@property (nonatomic, retain) Clamshell *clamshell;
@property (nonatomic, retain) NSMutableArray *arrayClamshells;
@property (nonatomic, retain) NSMutableArray *arrayConvertibles;
@property (nonatomic, retain) NSMutableArray *arrayDetachables;

@end

翻盖.h:

#import <Foundation/Foundation.h>

@interface Clamshell : NSObject<NSCoding>

@property (nonatomic, retain) NSString *subProductTitle;
@property (nonatomic, retain) NSString *subProductId;

@end

这是我解析数据的代码:

    NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData
                                                                     options:kNilOptions
                                                                       error:&error];


                productsDict = [json objectForKey:@"Products"];

                pcsArray = [[NSMutableArray alloc] init];

    dispatch_async (dispatch_get_main_queue (),
                            ^
                                for (NSDictionary *items in productsDict)
                                
                                    NSDictionary *pcsDict = [items objectForKey:@"Pcs"];

                                    for (NSDictionary *item1 in pcsDict) 

                                        PCs *pcs = [[PCs alloc] init];
                                        pcs.productId = [item1 objectForKey:@"product_id"];
                                        pcs.productTitle = [item1 objectForKey:@"product_name"];

                                        //for the category                                            
                                           pcs.myProductCategory = [[MyProductCategory alloc] init];
                                           pcs.myProductCategory = [item1 objectForKey:@"category"];

                                           NSMutableArray *clamshellDict = [pcs.myProductCategory valueForKey:@"Clamshells"];


                                           NSMutableArray *array = [[NSMutableArray alloc]init];

                                            for (NSDictionary *items2 in clamshellDict) 
                                                Clamshell *clam = [[Clamshell alloc] init];
                                                clam.subProductId = [items2 objectForKey:@"sub_category_id"];
                                                clam.subProductTitle = [items2 objectForKey:@"sub_category_name"];

                                                [array addObject:clam];// 
                                            

                                            pcs.myProductCategory.arrayClamshells = [NSMutableArray alloc] init]; //here it is crashing

pcs.myProductCategory.arrayClamshells = [array copy];
                                        

                                        [pcsArray addObject:pcs];
                                    

                                    NSLog(@"PCs array is = %@", pcsArray);
                                

                            );

但是当我初始化数组或为其设置任何值时它会崩溃。 错误信息是:

-[__NSCFDictionary setArrayClamshells:]: unrecognized selector sent to instance 0x7f8f16059730

 Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary setArrayClamshells:]: unrecognized selector sent to instance 0x7f8f16059730'

【问题讨论】:

setArrayClamshells 方法在哪里? @iDev 只是.arrayClamshells =时调用的默认setter方法。 是的,它看起来像 object.array 或 object setArray 在 arrayClamshells 属性中保留一个断点。尝试使用异常断点 您的问题似乎存在:pcs.myProductCategory = [item1 objectForKey:@"category"];。您将 NSDictionary 分配给 MyProductCategory,然后将其视为 NSDictionary(为什么会导致并解释崩溃错误)。另外,还有一些 alloc/init 显然做得不好。 【参考方案1】:

你的代码在这里

pcs.myProductCategory = [[MyProductCategory alloc] init];
pcs.myProductCategory = [item1 objectForKey:@"category"];

正在正确创建您的 MyProductCategory 实例,但随后将其替换为字典。您可能打算将第二行写为

NSDictionary *category = [item1 objectForKey:@"category"];

然后在下一行使用它来解压字典内容

【讨论】:

感谢@Wain 的回答。【参考方案2】:

错误是您有一行正确地将myProductCategory 初始化为您的自定义对象:

pcs.myProductCategory = [[MyProductCategory alloc] init];

但是在下一行中,您将其丢弃并将其设置为category 条目指定的字典:

pcs.myProductCategory = [item1 objectForKey:@"category"];

因此,当您到达以下行时,它会崩溃,因为myProductCategory 不再是MyProductCategory,而是NSDictionary

pcs.myProductCategory.arrayClamshells = [NSMutableArray alloc] init];

【讨论】:

以上是关于在 iOS 中使用数组解析 JSON 时出错的主要内容,如果未能解决你的问题,请参考以下文章

json解析时出错

在swift ios中解析NSJSON序列化中的json时出错

我如何解析 Json 对象或数组?我的代码哪里出错了?

在 RestKit 中解析空数组时出错

Apollo graphQL:在 iOS swift 中使用自定义标量时解码数组时出错

使用body.json()解析来自http.get()的响应时出错