在投射之前检查对象的类是否最好?

Tea*_*App 4 cocoa casting objective-c

我应该只是变换一个变量,还是用isKindOfClass:它来检查然后再进行投射?哪一个更好,效率更高?(好吧,效率不仅仅是一个问题.)我想string在下面成为一个NSString.

例:

NSString *string = (NSString *)result;
Run Code Online (Sandbox Code Playgroud)

要么:

if(![string isKindOfClass:[NSString class]]
{
   //cast it
} 
Run Code Online (Sandbox Code Playgroud)

Jos*_*ell 5

强制转换没有任何运行时效果.这只是给编译器的一个信息,你确定可以从一种类型分配到另一种类型(当你有一个类型时,它也会沉默警告"可能没有响应" id).

NSString * s = (NSString *)[NSNumber numberWithInt:0];
// The compiler will let you do this, but it's pointless, because:
[s floatValue];    // Okay; NSNumber also implements -floatValue
[s lowercaseString];    // Crashes; s is still an NSNumber instance, 
                        // which doesn't respond to -lowercaseString
Run Code Online (Sandbox Code Playgroud)

另一方面,isKindOfClass:在编译时没有任何影响; 它就像任何其他消息一样在运行时发送,然后确定其结果.

我不确定你想要实现什么,但我想不出通过组合这两种机制可以做的任何有用的事情.

没有理由isKindOfClass:在施法前发送,但不是出于你想的原因.要么你在编译时知道这个类,在这种情况下isKindOfClass:是没有意义的,要么你没有,在这种情况下,转换是无效的.

  • 我完全不同意将两者结合起来是没用的.将两者结合起来是唯一合理的方法.是的,你在编译时不知道这个类,这就是你通过`isKindOfClass:`检查它是否是某个类的原因.只有当它是某种类型(在if中)时,你才会将其投射并以方便且经过类型检查的方式使用它.如果它不是所需的类型,您可以抛出错误或什么都不做.例如,Java中的强制转换*完全*是1)运行时检查类和抛出错误(如果不是)的组合,以及2)转换编译时类型 (4认同)
  • `isKindOfClass:`检查确定你在运行时持有的对象确实是一个NSString(或其他).像你说的那样,演员沉默警告.当一个对象来自用户输入(例如,一个plist)并且您想要验证它是哪个类的实例时,将它们组合起来是值得的,然后将其视为这样的实例而不会堆积警告. (3认同)

arc*_*ght 3

虽然仅进行转换会更有效,但如果您首先检查结果是否如您所想,可能对您的应用程序更好。

这完全取决于您想要的安全程度