Смешивание функций C в классе Objective-C - PullRequest
38 голосов
/ 29 апреля 2009

Я пишу класс 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);
  1. Может / как я могу вызвать метод Objective-C вместо этого?
  2. Можно / нужно ли смешивать функции C с моими вызовами Objective-C?
  3. Как смешать функции C с методами Objective-C?

Ответы [ 4 ]

47 голосов
/ 06 мая 2009

Возможно смешивание методов и функций C и Objective-C. Вот простой пример использования SQLite API в приложении для iPhone:

Загрузить файл Zip (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

25 голосов
/ 29 апреля 2009

Чтобы вызвать код Objective-C из обратного вызова C, я бы использовал что-то вроде:

void * refToSelf;
int cCallback()
{
    [refToSelf someMethod:someArg];
}

@implementation SomeClass
- (id) init
{
     self = [super init];
     refToSelf = self;
}
- (void) someMethod:(int) someArg
{
}
8 голосов
/ 17 января 2010

Может / как я могу вызвать метод Objective-C вместо этого?

Вы не можете.

Можно / нужно ли смешивать функцию C с моим вызовом Objective-C?

Да. Напишите функцию C и используйте ее в качестве обратного вызова для функции CF.

Как смешать функцию C с методами Objective-C?

Вы можете установить self в качестве указателя info в вашей контекстной структуре. Это будет передано в обратный вызов. Затем в обратном вызове приведите указатель info обратно к id:

MyClass *self = (id)info;

Затем вы можете отправлять self сообщений. Вы по-прежнему не можете напрямую получить доступ к переменным экземпляра, так как функция C находится вне раздела @implementation Вы должны будете сделать их свойства. Вы можете сделать это с расширением класса . (Вопреки тому, что говорится в этом документе, вы не объявляете расширение внутри @implementation, но в одном файле с ним, как правило, прямо над ним.)

5 голосов
/ 29 апреля 2009

В этой ситуации я всегда находил полезным сделать оболочку Obj-C поверх C API. Реализуйте то, что вам нужно для использования функций C, и создайте класс Objective-C (или два) поверх него, так что это увидит весь внешний мир. Например, в случае такого обратного вызова вы можете создать функцию C, которая вызывает методы делегирования Obj-C для других объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...