Objective-C安全铸造宏

时间:2010-07-13 02:27:13

标签: objective-c macros

我在Objective-C中编写了一个宏来执行安全转换。以下是目前的情况:

#define SAFE_CAST(OBJECT, TYPE) ([OBJECT isKindOfClass:[TYPE class]] ? (TYPE *) OBJECT: nil)

这非常有效,但如果有一种方法可以将OBJECT存储在一个变量中,那么它就不会被调用两次。例如,使用宏:

NSString *str = SAFE_CAST([dictinary objectForKey:key], NSString);
扩展宏时,

会产生与此类似的代码:

NSString *str = ([[dictinary objectForKey:key] isKindOfClass:[NSString class]] ? (NSString *) [dictinary objectForKey:key]: nil);

我更喜欢它更像这样的工作:

id obj = [dictionary objectForKey:key];
NSString *str = ([obj objectForKey:key] isKindOfClass[NSString class]] ? (NSString *) obj : nil);

感谢。

3 个答案:

答案 0 :(得分:10)

您可以使用名为声明statement expressions的GCC扩展程序

#define SAFE_CAST(OBJECT, TYPE) ({ id obj=OBJECT;[obj isKindOfClass:[TYPE class]] ? (TYPE *) obj: nil; })

那就是说,我认为这种情况通常很糟糕,你需要经常使用SAFE_CAST。 切勿将不同类的对象放在数组中;永远不要为不同类的UI对象重用动作消息(IBAction)someAction:(id)sender。那么您通常不需要使用SAFE_CAST

答案 1 :(得分:4)

如果你真的认为你必须这样做,你可以使用一个函数:

#define SAFE_CAST(Object, Type) (Type *)cast_helper(Object, [Type class])
static id cast_helper(id x, Class c) {
    return [x isKindOfClass:c] ? x : nil;
}

答案 2 :(得分:0)

所以这样写,只需将它包装在do {}中(0)< - 而不只是括号中。

#define SAFE_CAST(OBJECT, TYPE, VAR) do { \
    id obj = OBJECT; \
    VAR = [obj isKindOfClass:[TYPE class]] ? (TYPE *) obj : nil; \
} while(0)
相关问题