Смешивание функций C в классе Objective-C
-
03-07-2019 - |
Вопрос
Я пишу класс 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?
Решение
Возможно смешивание методов и функций C и Objective-C, вот простой пример, который использует SQLite API в приложении для iPhone:(сайт курса)
Функции 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 для других объектов.