cocoa touch — проверить, является ли объект объектом objective-C.

#iphone #c #cocoa-touch #ios #object

#iPhone #c #cocoa-touch #iOS #объект

Вопрос:

Предположим, у меня есть объект. Может быть объектом objective-C; может быть объектом C . Есть ли способ проверить, какой из них не вызовет никаких исключений?

РЕДАКТИРОВАТЬ: я рад использовать любую конструкцию, которая работает, включая шаблоны, если они будут выполнять эту работу.

Комментарии:

1. является ли использование @try / @catch опцией?

2. Насколько я могу судить, нет. @try / @catch — это конструкция objective C, и, похоже, она выдает ошибку при задании объекта, не являющегося ObjectiveC.

3. У вас действительно есть объект или просто указатель из какого-либо источника, в котором удалена информация о типе; это может быть либо адрес объекта C , либо идентификатор какого-либо объекта Objective-C.

4. Я использую его несколькими способами, все они связаны с отладочным кодом. Если мне нужно постоянно отслеживать, является ли мой объект Objective C или C , это еще одна вещь, которую нужно постоянно отслеживать. Кроме того, в некоторых случаях адрес может поступать из входных данных программиста, поэтому программисту также потребуется ввести, является ли объект объектом Objective C.

Ответ №1:

Друг нашел это в блоге Cocoa with Love. По-видимому, проблема не тривиальна.

Комментарии:

1. Как насчет objc_lookUpClass (const char * name) и objc_getClass (const char * name), если вы знаете имя класса C ? Зарегистрированы ли классы C во время выполнения obj-c, когда в таких объектах отсутствует реализация isa? Я что-то упускаю?

Ответ №2:

Поскольку вы можете использовать шаблоны, вы могли бы сделать что-нибудь, где вы создаете некоторый тип функции, которая принимает общий аргумент шаблона, а затем создаете экземпляр вашего базового класса со всеми классами, которые вы используете из C , с помощью макроса. Если это не класс C , то функция возвращает false. Так, например:

 //...in some header file
template<typename T>
bool is_cplusplus(const T* type) { return false; }

#define IS_CPLUSPLUS_T(class) 
           template<> 
           inline bool is_cplusplus(const class* type) { return true; }

//...now use the macro to declare all your C   classes as "true" in the return 
//from is_cplusplus()
IS_CPLUSPLUS_T(my_class1)
IS_CPLUSPLUS_T(my_class2)

//...now use in some code in a separate .cpp file or .mm file, etc.
my_class1 a_class;
if (is_cplusplus(amp;a_class))
{
    //do something
}
  

Я специально использую здесь указатели, а не ссылки, потому что, насколько я понимаю, вы можете создать экземпляр шаблона C с указателем на объект Objective-C, в то время как создание экземпляров с самими объектами Objective-C не работает. Если это предположение неверно, то вы можете немного упростить жизнь, перейдя с указателей на ссылки.

Комментарии:

1. Конечно, но я не хочу увеличивать объекты.

2. Можете ли вы использовать шаблоны в своем решении? Я не эксперт по Objective-C , но я знаю, что часто шаблоны C и объекты Objective-C не работают должным образом, поэтому дайте мне знать, можете ли вы использовать шаблоны в своем решении, чтобы хотя бы определить, является ли что-то классом C …

3. @William Jockusch: Хорошо, я предпринимаю еще одну попытку найти ответ… надеюсь, это не будет слишком громоздким…

Ответ №3:

Я думаю, что это можно сделать намного проще, чем это, если тип доступен статически (как подразумевается при использовании шаблона в качестве опции). Объекты Objective-C будут неявно конвертироваться в NSObject и / или объекты ‘id’ — C не будут (без по крайней мере пользовательского кода для каждого класса для добавления оператора приведения).

 // by default, consider it to not be Objective-C.
// C   object, pointer, built-in, or whatever.
template<typename T>
bool isObjectiveC(const Tamp; ptr) {return false;}
// specialise for any Objective-C object
template<>
bool isObjectiveC(const NSObject*amp; ptr) {return true;}
template<>
bool isObjectiveC(const idamp; theID) {return true;}
  

Прототипы функций здесь передают параметр с помощью constamp; потому что у меня были проблемы с шаблонизацией с типами Objective-C, возвращаемыми сообщениями Objective-C, и это, похоже, работает там, где обычный NSObject * не работает.