Смешивание функций C в классе Objective-C
Я пишу класс Objective-C, но он использует API, написанный на C. Это в основном отлично, поскольку смешивание вызовов C с вызовами Objective-C вызывает несколько проблем.
Однако для вызова одного из API требуется метод обратного вызова (пример):
success = CFHostSetClient(host, MyCFHostClientCallBack, &context);
Где MyCFHostClientCallBack
- функция C, определенная следующим образом:
static void MyCFHostClientCallBack(CFHostRef host, CFHostInfoType typeInfo, const CFStreamError *error, void *info);
- Может/Как я могу назвать метод Objective-C вместо этого?
- Может/должен ли я смешивать функции C с моими вызовами Objective-C?
- Как мне смешивать функции C с методами Objective-C?
Ответы
Ответ 1
Возможны методы и функции Mixing C и Objective-C, вот простой пример, который использует SQLite API в приложении iPhone: (сайт курса)
Загрузите Почтовый файл (09_MySQLiteTableView.zip)
Функции C должны быть объявлены вне @implementation
в файле Objective-C (.m).
int MyCFunction(int num, void *data)
{
//code here...
}
@implementation
- (void)MyObjectiveCMethod:(int)number withData:(NSData *)data
{
//code here
}
@end
Поскольку функция C находится вне @implementation
, она не может вызывать методы типа
[self doSomething]
и не имеет доступа к иварам.
Это можно работать до тех пор, пока функция обратного вызова принимает параметр типа userInfo
или context
, обычно типа void*
. Это можно использовать для отправки любого объекта Objective-C в функцию C.
Как и в пример кода, это можно манипулировать с помощью обычных операций Objective-C.
Кроме того, прочитайте этот ответ: Смешивание функций C в классе Objective-C
Ответ 2
Чтобы вызвать код Objective-C из обратного вызова C, я бы использовал что-то вроде:
void * refToSelf;
int cCallback()
{
[refToSelf someMethod:someArg];
}
@implementation SomeClass
- (id) init
{
self = [super init];
refToSelf = self;
}
- (void) someMethod:(int) someArg
{
}
Ответ 3
Can/Как мне вместо этого использовать метод Objective-C?
Вы не можете.
Может ли/я должен смешивать функцию C с моим вызовом Objective-C?
Да. Напишите функцию C и используйте ее как обратный вызов функции CF.
Как мне добавить функцию C с помощью методов Objective-C?
Вы можете установить self
в качестве указателя info
в вашей структуре контекста. Это будет передано на обратный вызов. Затем в обратном вызове верните указатель info
на id
:
MyClass *self = (id)info;
Затем вы можете отправлять сообщения self
. Однако вы по-прежнему не можете напрямую обращаться к переменным экземпляра, поскольку функция C находится вне раздела @implementation
. Вы должны будете сделать их свойствами. Вы можете сделать это с помощью расширения . (В отличие от того, что говорит этот документ, вы не должны объявлять расширение внутри @implementation
, но в том же файле с ним, как правило, прямо над ним.)
Ответ 4
То, что я всегда нашел полезным в этой ситуации, заключается в создании обертки Obj-C поверх C API. Внесите то, что вам нужно для использования функций C, и постройте класс Objective-C (или два) поверх него, чтобы весь внешний мир увидел. Например, в случае обратного вызова вы можете создать функцию C, которая вызывает методы делегирования Obj-C для других объектов.