Подтвердить что ты не робот

Смешивание функций 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?
4b9b3361

Ответ 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 для других объектов.