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

时间:2022-08-24 07:00:57

Is there any way to do the following at compile-time?

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

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

An dummy situation where this could be used is to define the __add_macro below.

可以使用这个虚拟场景来定义下面的__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

Clarification/Simplification

澄清/简化

I guess there is no way to do this with one macro. But I still need it to warn if the macro is being used on the wrong datatype. Those two types are: object and non-object).

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

To check if it is an object, this works:

要检查它是否是一个对象,可以这样做:

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

What I need:

我所需要的东西:

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

Again, I need this to happen at compile-time. And it can either throw an error or warning.

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

Thanks

谢谢

2 个解决方案

#1


5  

When you declare an int variable you can really only put an int value in it.

当你声明一个int变量时,你只能在里面加上一个int值。

While this is Objective-C, and hence C, so you can bypass just about every type protection mechanism that exists, this is not to be advised. Indeed there is no guarantee whatsoever that a, say, NSNumber reference will even fit into an int variable - and more than enough chance that if you try, and bypass any warnings, some bits will just get tossed making the reference invalid.

虽然这是Objective-C,因此是C,所以您可以绕过存在的几乎所有类型保护机制,但这是不建议的。实际上,没有任何保证,例如,NSNumber引用甚至可以放入一个int变量中——如果您尝试,并且绕过任何警告,那么一些位就会被抛出,使引用无效。

So, no, while you can tell what class an object reference refers to, you cannot in general tell whether a variable has an integer value or an object reference in it - you shouldn't even try to put these two very different things into the same variable.

所以,不,虽然你可以知道一个对象引用指的是什么类,但你一般不能知道一个变量是有一个整数值还是有一个对象引用——你甚至不应该把这两个非常不同的东西放在同一个变量中。

Answer 2

回答2

Patrick, your comments and clarification seem to suggest you are not trying to do what the question starts out by asking (how do you determine if the value in an int is an object - answered above, you don't), but something rather different...

Patrick,你的评论和澄清似乎表明你并不是在试图按照问题的开头提问(你如何确定一个int中的值是否是一个对象?答案在上面,你没有),而是一些相当不同的东西……

I think what you're after is function overloading, and as you seem to be trying to use macros, maybe inline functions as well. Clang supports function overloading, here is program fragment which may show you how to solve your problem:

我认为你所追求的是函数重载,当你试图使用宏时,也可能是内联函数。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);
}

The above code when run outputs:

以上代码在运行时输出:

int version called: 5
NSNumber version called: 42

Clang 3 compiles the above code inlining the two calls, so you get the same code as using macros.

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

#2


0  

please don't mix between scalar values and pointers to objects... it will not end well.

请不要混淆标量值和指向对象的指针……这不会有好结果。

if you insist you can do something with Objective-C++

如果你坚持,你可以用objective - c++做些什么

something like

类似的

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

#1


5  

When you declare an int variable you can really only put an int value in it.

当你声明一个int变量时,你只能在里面加上一个int值。

While this is Objective-C, and hence C, so you can bypass just about every type protection mechanism that exists, this is not to be advised. Indeed there is no guarantee whatsoever that a, say, NSNumber reference will even fit into an int variable - and more than enough chance that if you try, and bypass any warnings, some bits will just get tossed making the reference invalid.

虽然这是Objective-C,因此是C,所以您可以绕过存在的几乎所有类型保护机制,但这是不建议的。实际上,没有任何保证,例如,NSNumber引用甚至可以放入一个int变量中——如果您尝试,并且绕过任何警告,那么一些位就会被抛出,使引用无效。

So, no, while you can tell what class an object reference refers to, you cannot in general tell whether a variable has an integer value or an object reference in it - you shouldn't even try to put these two very different things into the same variable.

所以,不,虽然你可以知道一个对象引用指的是什么类,但你一般不能知道一个变量是有一个整数值还是有一个对象引用——你甚至不应该把这两个非常不同的东西放在同一个变量中。

Answer 2

回答2

Patrick, your comments and clarification seem to suggest you are not trying to do what the question starts out by asking (how do you determine if the value in an int is an object - answered above, you don't), but something rather different...

Patrick,你的评论和澄清似乎表明你并不是在试图按照问题的开头提问(你如何确定一个int中的值是否是一个对象?答案在上面,你没有),而是一些相当不同的东西……

I think what you're after is function overloading, and as you seem to be trying to use macros, maybe inline functions as well. Clang supports function overloading, here is program fragment which may show you how to solve your problem:

我认为你所追求的是函数重载,当你试图使用宏时,也可能是内联函数。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);
}

The above code when run outputs:

以上代码在运行时输出:

int version called: 5
NSNumber version called: 42

Clang 3 compiles the above code inlining the two calls, so you get the same code as using macros.

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

#2


0  

please don't mix between scalar values and pointers to objects... it will not end well.

请不要混淆标量值和指向对象的指针……这不会有好结果。

if you insist you can do something with Objective-C++

如果你坚持,你可以用objective - c++做些什么

something like

类似的

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