Вопрос по objective-c – Как проверить, является ли переменная объектом?

3

Есть ли способ сделать следующее во время компиляции?

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

Clarification/Simplification

Я думаю, что нет способа сделать это с одним макросом. Но мне все еще нужно предупредить, если макрос используется с неверным типом данных. Эти два типа:object а такжеnon-object).

Чтобы проверить, если это объект, это работает:

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

Что мне нужно:

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

Опять же, мне нужно, чтобы это произошло во время компиляции. И это может выдать ошибку или предупреждение.

Спасибо

попробуйте @encode. я думаю, тебе нужно два макроса Bryan Chen
Если бы был какой-то способ, я мог бы проверить@encode или простоtypeof во время компиляции, чтобы гарантировать, что тип неid или что-нибудь, что считаетсяid, это будет работать. Но я не нашел способа проверить равенство типов во время компиляции. Patrick

Ваш Ответ

2   ответа
5

int Переменная вы можете действительно положить толькоint ценность в этом.

Хотя это Objective-C и, следовательно, C, так что вы можете обойти практически все существующие механизмы защиты типов, это неadvised, На самом деле нет никаких гарантий, что, скажем,NSNumber ссылка будет даже вписываться вint переменная - и более чем достаточно шансов, что если вы попытаетесь обойти любые предупреждения, некоторые биты просто будут брошены, делая ссылку недействительной.

Таким образом, нет, хотя вы можете сказать, к какому классу относится ссылка на объект, вы в целом не можете определить, содержит ли переменная целочисленное значение или ссылку на объект - вы даже не должны пытаться поместить эти две совершенно разные вещи в та же переменная.

Answer 2

Патрик, ваши комментарии и разъяснения, кажется, говорят о том, что вы не пытаетесь сделать то, что начинается с вопроса (как определить, что значение вint является объектом - ответили выше, вы не т), но что-то скорее другое ...

Я думаю, что вы послеfunction overloadingи, как вы, кажется, пытаетесь использовать макросы, возможно, встроенные функции. 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 компилирует приведенный выше код, заключающий два вызова, так что вы получаете тот же код, что и при использовании макросов.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededget_primitive(varname, source)Error: User Rate Limit ExceededvarnameError: User Rate Limit ExceededsourceError: User Rate Limit Exceededstrcmp([source objCType],@encode(__typeof(var)))Error: User Rate Limit Exceeded Patrick
0

не смешивайте скалярные значения и указатели на объекты ... это не закончится хорошо.

если вы настаиваете, что вы можете сделать что-то с Objective-C ++

что-то вроде

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

Похожие вопросы