0

我有一本字典。我提取其中一个值如下:

NSString *magicValue= [filterDict valueForKey:[filterDict allKeys][0]];
[SomeClass foo: magicValue];

而 foo 是:

- (void)foo:(NSString*)magicValue
{
    NSLog("magicValue is string:%@",[magic isKindOfClass:[NSString class]] ? @"YES" : @"NO");
    NSLog("magicValue is number:%@",[magic isKindOfClass:[NSNumber class]] ? @"YES" : @"NO");
}

如果字典值为数字,magicValue 将为NSNumber. 所以定义的字符串指针将指向一个NSNumber. 日志将返回 yes 进行号码检查。

我从未对此类方法添加保护,以检查“magicValue”是什么类。我假设当我定义一个带有字符串参数的方法时,它将是字符串。

我应该开始考虑这种行为并始终添加检查,还是以这种方式将该字典值分配给魔法并使用我的方法的人的错。我需要一些最佳实践建议以及如何处理。

这个问题可能已经回答了,但我不知道如何搜索。

4

2 回答 2

1

大多数时候你应该知道你引用的是什么类,或者至少你想要它是什么。如果您有一个意外的类,这可能会导致崩溃,具体取决于您发送给它的消息,您可以调试您的代码并获得正确的参考。

有时,通常在处理继承时,您需要在运行时而不是在编译时确定类。这时候,isKindOfClass:可能会有用。如果您知道一个值可能是许多类之一,我会将其提取为 anid然后在最后一刻将其转换为

id value = [[NSUserDefaults standardUserDefaults] valueForKey:aKey];
if ([value isKindOfClass:[MyClass class]]) {
    // Do one thing
}
else {
    // Do another
}
于 2015-04-29T08:32:28.840 回答
1

简短的回答:不,如果没有特殊原因,不要检查。

长答案:

您必须区分两种情况:

A. 使用id

您有一个类型为 的变量或返回值id。这是在您的示例-valueForKey:中。键入的原因是保持方法通用。即使在理论上是可能的,但在实践中,这种情况下的类型不匹配非常罕见,并且在开发过程中可以快速检测到。出于不同的动机,我在一次公开演讲中询问了观众(>200 人),他们在制作过程中有多少次出现这样的打字错误。对于所有听众,他们的所有应用程序版本中的所有应用程序都有 1 个(换句话说:一个!)案例。只需忘记这种风险。这是使用静态类型语言(Java、C++、Swift)的开发人员的焦虑。

B. 错误分配

如果你没有id类型,仍然可以做这样的技巧。(有时您想这样做。这是动态类型的优势。)有两个子类别:

你可以隐式地做到这一点:

NSString *string = [NSNumber numberWithInt:1];

编译器会警告你。所以一切都很好,因为开发人员会看到他的错误。您不必保护他或您的代码。

可以明确地做到这一点:

NSString *string = (NSString*)[NSNumber numberWithInt:1];

在这种情况下,代码可能会中断。但他明确地做到了。如果它是错误的,开发人员有犯罪能量这样做,你不必保护他免受他自己的伤害。

于 2015-04-29T08:33:34.177 回答