【问题标题】:Performance penalty using respondsToSelector使用 respondsToSelector 的性能损失
【发布时间】:2012-08-24 22:57:14
【问题描述】:

每当 JSON 响应具有无效值时,我将重构大量旧代码,以使客户端对错误的服务器响应和日志异常更加健壮,并且我正在考虑检查每个正在解析的节点的有效性(数据类型)使用 respondsToSelector。

我正在检查响应中的数据类型(int、bool 等)

[[json objectForKey: @"feature_enabled"] boolValue], 

如果@"feature_enabled" 节点的值不是 0 或 1,则会导致应用崩溃

要解决这个问题,我会这样做

if ([[json objectForKey: @"feature_enabled"] respondsToSelector: @selector(boolValue)]){
          BOOL featureEnabled = [[json objectForKey: @"feature_enabled"] boolValue];
}else{
          Log Exception
}

我没有对此代码进行任何类型的性能分析,但我想知道如果我要检查每个 JSON 响应对选择器的响应,是否有人可以建议我应该期望什么样的性能损失打算解析。

感谢任何指向信息来源的指针!

【问题讨论】:

    标签: objective-c ios xcode performance respondstoselector


    【解决方案1】:

    respondsToSelector: 检查零。它不是空的,它调用 IMP lookUpMethod(Class cls, SEL sel, BOOL initialize, BOOL cache, id inst) 从 IMP 缓存中返回方法(使用 CacheLookup 宏)。如果没有找到,它会尝试填充缓存,在类本身中查找方法,这涉及对超类重复操作。如果失败,它将运行forwarding mechanism

    isKindOfClass: 比较两个类的 isa 指针。如果失败,它将与超类重复,这只是struct objc_class 中的字段“super_class”。

    所以区分两个对象的正确方法是isKindOfClass:

    请注意,处理您的 JSON 数据将比上述所有内容慢数亿倍。找不到选择器不会导致系统停止或任何事情。

    【讨论】:

    • 感谢您的回复,非常放心。由于我在响应([[json objectForKey:@"feature_enabled"] boolValue])中检查数据类型(int、bool 等),如果@"feature_enabled" 节点的值不是 0 或 1,则应用程序会崩溃. 所以在那种情况下我唯一的选择是使用 -respondsToSelector?
    • Apple 解析器返回 NSString、NSNumber、NSArray、NSDictionary 或 NSNull。布尔值是 NSNumber。做isKindOfClass:[NSNumber class],如果不通过则忽略节点,如果通过则调用boolValue。
    • 更正:“像 respondsToSelector: 和 isKindOfClass 这样的方法:只查看继承层次结构,从不查看转发链。”
    【解决方案2】:

    您可能需要考虑使用 isKindOfClass 我认为这是最好的性能:

    if([[yourDictionary objectForKey:@"yourKey"] isKindOfClass:[NSArray class]]) { //假设它是一个数组并处理它 }

    【讨论】:

    • 同意。 -isKindOfClass: 只需要检查 Class *isa 指针,而 -respondsToSelector: 可能会做一些运行时的事情。
    • 实际上 -isMemberOfClass: 会检查 isa。 -isKindOfClass:还需要检查所有超类的 isa。
    • @rooster117 , @"Jack Lawrence" 感谢您的回答。我相信 isKindOfClass 仅适用于类(NSArray、NSDictionary、NSString 等),但不适用于检查特定数据类型(int、bool 等)。所以在这种情况下,我唯一的选择是使用 -respondsToSelector?
    • int、bool 或其他原语没有选择器,因为它们不是对象,因此您将无法对它们进行检查。您只需将字符串从 json 转换为 nsnumbers 并对其进行检查。
    猜你喜欢
    • 2016-12-20
    • 1970-01-01
    • 2010-11-09
    • 2012-02-08
    • 2019-02-09
    • 2010-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多