在Objective C中断言对象类

jba*_*100 5 macros class objective-c nsassert

我经常发现自己断言Objective-C中某个类的对象"isKindOfClass".我是这样做的:

NSAssert([obj isKindOfClass:[AClass class]], @"%@ should be kind of class %@", obj, [[AClass class] description]);
Run Code Online (Sandbox Code Playgroud)

我想知道为它做出捷径的最好方法.我正在考虑定义一个宏,例如:

#define NSClassAssert(obj, class)  NSAssert([obj isKindOfClass:class], @"%@ should be of class %@", obj, [class description])
Run Code Online (Sandbox Code Playgroud)

我担心这可能会导致一些令人讨厌的难以处理的编译错误或运行时问题,这样做是否存在根本性的错误,是否有更明智的方法呢?

mip*_*adi 3

人们首先必须问清楚为什么要这样做。你说:

考虑到目标 c 的宽容性和动态性,我喜欢使代码“防滥用”。我没有收到无法识别的选择器消息,而是收到一条消息,告诉我该对象应该属于哪个类。

如果您将对象传递给与签名中声明的类型不匹配的方法,即,您将执行以下操作:

- (void)doSomething:(NSArray *)array { /* Do something * }

- (void)doSomethingElse
{
    NSString *string = @"my string";
    [self doSomething:string];
}
Run Code Online (Sandbox Code Playgroud)

您会收到警告,因此您应该在编译时知道对象类型不匹配。

当然,当使用更通用的类型(例如 )时,这并不能保护您id,但是如果您担心无法识别的选择器,您确实应该检查对象是否响应该选择器,而不是使用断言:

- (id)doSomething:(id)obj
{
    if ([obj respondsToSelector:@selector(calculateSomething)]) {
        return [obj calculateSomething];
    } else {
        NSLog(@"%@ does not respond to calculateSomething", obj);
    }
}
Run Code Online (Sandbox Code Playgroud)

或者使用协议来检查方法的可用性。


然而,话虽如此,是的,您的宏将达到您的预期目的。