Objective-Cクラスを作成していますが、Cで作成されたAPIを使用しています。C呼び出しとObjective-C呼び出しを混在させると問題はほとんど発生しないため、これで問題はほとんどありません。
ただし、API呼び出しの1つには、コールバックメソッドが必要です(例):
success = CFHostSetClient(Host, MyCFHostClientCallBack, &context);
MyCFHostClientCallBack
は、次のように定義されたC関数です。
static void MyCFHostClientCallBack(CFHostRef Host, CFHostInfoType typeInfo, const CFStreamError *error, void *info);
CとObjective-Cのメソッドと機能を混在させることが可能です。iPhoneアプリ内でSQLite APIを使用する簡単な例を次に示します。( course site )
Zipファイル(09_MySQLiteTableView.Zip) をダウンロードします
C関数は、Objective-C(.m)ファイルの@implementation
の外側で宣言する必要があります。
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操作で操作できます。
さらに、この回答をお読みください: Objective-CクラスでのC関数の混合
CコールバックからObjective-Cコードを呼び出すには、次のようなものを使用します。
void * refToSelf;
int cCallback()
{
[refToSelf someMethod:someArg];
}
@implementation SomeClass
- (id) init
{
self = [super init];
refToSelf = self;
}
- (void) someMethod:(int) someArg
{
}
これの代わりにObjective-Cメソッドを呼び出すことができますか、どのように呼び出すことができますか?
できません。
Objective-C呼び出しにC関数を混在させることはできますか/すべきですか?
はい。 C関数を記述し、CF関数へのコールバックとして使用します。
C関数とObjective-Cメソッドを混在させるにはどうすればよいですか?
self
をコンテキスト構造のinfo
ポインターとして設定できます。それはコールバックに渡されます。次に、コールバックで、info
ポインターをid
にキャストします。
MyClass *self = (id)info;
その後、self
メッセージを送信できます。ただし、C関数は@implementation
セクションの外側にあるため、インスタンス変数に直接アクセスすることはできません。それらをプロパティにする必要があります。 クラス拡張 でこれを行うことができます。 (その文書が述べていることとは反対に、@implementation
内で拡張子を宣言するのではなく、それと同じファイルで、一般的にはそのすぐ上で宣言します。)
この状況で私がいつも助けになっているのは、C APIの上にObj-Cラッパーを作成することです。 C関数を使用するために必要なものを実装し、その上にObjective-Cクラス(または2つ)を構築します。これにより、外の世界がすべて見えるようになります。たとえば、このようなコールバックの場合、他のオブジェクトのObj-Cデリゲートメソッドを呼び出すC関数を作成できます。