如何检查变量是否为对象?

时间:2012-06-01 04:37:22

标签: objective-c

有没有办法在编译时执行以下操作?

int anInteger = 0;
__if_object(anInteger) {
    // send object some messages
}
__if_primitive(anInteger) {
    // do something else
}

可以使用的虚拟情况是在下面定义__add_macro。

#define __add_macro(var, val) __something_goes_here__

int i = 1;
MyInteger* num = [[MyNumber alloc] initWithValue:1]

__add_macro(i, 4);
__add_macro(num, 4);

// both should now hold 5

澄清/简化

我想用一个宏无法做到这一点。但是我仍然需要它来警告宏是否在错误的数据类型上使用。这两种类型是:objectnon-object)。

要检查它是否是一个对象,这可行:

#define __warn_if_not_object(var) if(0){[(var) class];}

我需要什么:

#define _warn_if_object(var) if(0){__something_here__}

同样,我需要在编译时发生这种情况。它可能会引发错误或警告。

由于

2 个答案:

答案 0 :(得分:5)

当您声明int变量时,您实际上只能在其中添加int值。

虽然这是Objective-C,因此是C,所以你可以绕过几乎所有存在的类型保护机制,这不是建议。事实上,无法保证NSNumber引用甚至可以适用于int变量 - 并且如果你尝试并绕过任何警告,那么一些比特就会被抛出的机会绰绰有力。使参考无效。

所以,不,虽然你可以告诉对象引用引用什么类,你通常不能告诉变量是否有一个整数值或一个对象引用 - 你甚至不应该试图把这两个非常不同事物变成了同一个变量。

回答2

帕特里克,你的评论和澄清似乎暗示你不是试图通过询问(如何确定int中的值是否是一个对象 - 来解决问题的开始 - 在上面回答,你不要t),但有些不同......

我认为你所追求的是函数重载,而你似乎正在尝试使用宏,也许是内联函数。 Clang支持函数重载,这里是程序片段,可以告诉你如何解决你的问题:

// Clang likes prototypes so let's give it some
// The following declares two overloaded inline functions:
NS_INLINE void __attribute__((overloadable)) byType(int x);
NS_INLINE void __attribute__((overloadable)) byType(NSNumber *x);

// now some simple definitions:
NS_INLINE void __attribute__((overloadable)) byType(int x)
{
   NSLog(@"int version called: %d", x);
}

NS_INLINE void __attribute__((overloadable)) byType(NSNumber *x)
{
   NSLog(@"NSNumber version called: %@", x);
}

// now call them, automatically selecting the right function
// based on the argument type
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
   int x = 5;
   NSNumber *y = [NSNumber numberWithInt:42];

   byType(x);
   byType(y);
}

运行输出时的上述代码:

int version called: 5
NSNumber version called: 42

Clang 3编译上面代码内联两个调用,因此您获得与使用宏相同的代码。

答案 1 :(得分:0)

请不要在标量值和指向对象的指针之间混合......它不会很好地结束。

如果你坚持要用Objective-C ++做点什么

类似

int sum(int,int);
NSNumber * sum(NSNumber *, NSNumber *);