gpt4 book ai didi

iphone - 转换后的 Objective-C 类类型不匹配

转载 作者:行者123 更新时间:2023-11-28 22:46:37 24 4
gpt4 key购买 nike

在使用 NSJSONSerialization 解析来自网络服务的 JSON 响应后,我使用 +isKindOfClass: 来确保服务器返回我期望的数据类型。使用这种方法时,我遇到了一些奇怪的行为,我将用一个例子来说明。

考虑以下对象:

// Definitions
NSDictionary *son = @{ @"firstname" : @"James", @"lastname" : @"Appleseed" };
NSDictionary *daughter = @{ @"firstname" : @"Susan", @"lastname" : @"Appleseed"};
NSArray *children = @[son, daughter];
NSDictionary *father = @{ @"firstname" : @"John", @"lastname" : @"Appleseed" };
NSDictionary *family = @{@"children" : children, @"father" : father};
NSDictionary *pedigree = @{@"family" : family };

这些对象表示从服务器返回的反序列化 JSON。现在,如果我想使用 children 数组来使用 NSArray 的 -count 计算有多少 child ,我需要确保 children 对象是一个 NSArray。例如,如果子对象恰好是一个字符串,而应用需要一个数组,它就会崩溃,因为字符串没有实现 count 方法。考虑以下实现所述检查的代码序列:

// First test
id _family = [pedigree objectForKey:@"family"];
if ([_family isKindOfClass:[NSDictionary class]])
{
NSDictionary *_family = (NSDictionary *)_family;
id _children = [_family objectForKey:@"children"];

NSLog(@"Children: %@", _children);
NSLog(@"Children classname: %@", NSStringFromClass(children.class));

if ([_children isKindOfClass:[NSArray class]]) {
NSLog(@"Children is an NSArray");
} else {
NSLog(@"Children is not an NSArray");
}
} else {
NSLog(@"Family is not an NSDictionary");
}

运行这段代码后,控制台输出如下:

Children: (null)
Children classname: __NSArrayI
Children is not an NSArray

控制台输出看起来非常不寻常,甚至自相矛盾。当它的类名是 __NSArrayI 时, child 怎么可能不是 NSArray?

经过一番调试,我发现有两种方法可以解决这个问题:

  1. 删除这一行 NSDictionary *_family = (NSDictionary *)_family;
  2. 为转换变量使用不同于 _family 的名称

如何解释这种行为?

最佳答案

行内

NSDictionary *_family = (NSDictionary *)_family;

您在当前作用域中定义了一个新变量_family,这使得外部变量_family 不可见。如果使用 ARC 编译,Objective-C 指针将初始化为 nil

和输出不矛盾,因为你打印

NSStringFromClass(children.class);

children的类(没有下划线),是一个数组。但是 _children(带下划线)是 nil 因为 _family 如上所述是 nil。

事实上,如果您需要字典,则不需要类型转换。你可以这样做

NSDictionary *_family = [pedigree objectForKey:@"family"];
if ([_family isKindOfClass:[NSDictionary class]])
{
NSArray *_children = [_family objectForKey:@"children"];

if ([_children isKindOfClass:[NSArray class]]) {
NSLog(@"Children is an NSArray");
} else {
NSLog(@"Children is not an NSArray");
}
} else {
NSLog(@"Family is not an NSDictionary");
}

关于iphone - 转换后的 Objective-C 类类型不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13072392/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com