Вопрос

Я пишу класс 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?
Это было полезно?

Решение

Возможно смешивание методов и функций 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]

и не имеет доступа к ivars.

С этим можно справиться до тех пор, пока функция обратного вызова не выполнит userInfo или context параметр типа, обычно имеющий тип void*.Это может быть использовано для отправки любого объекта Objective-C в функцию C.

Как в пример кода, этим можно манипулировать с помощью обычных операций Objective-C.

Кроме того, пожалуйста, прочтите этот ответ: Смешивание функций C в классе Objective-C

Другие советы

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

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

@implementation SomeClass
- (id) init
{
     self = [super init];
     refToSelf = self;
}
- (void) someMethod:(int) someArg
{
}

Могу ли / Как мне вызвать метод Objective-C вместо этого?

Ты не можешь.

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

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

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

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

MyClass *self = (id)info;

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top