14

私は機能を持っています:

  myFunction (MyProc callback, void * ref)

この関数は、Objective-Cクラス内から呼び出されます。関数には、コールバック(クラス内の関数)へのポインターと参照が渡されます。コールバックは静的に呼び出され、コンテキストがないため、参照が必要です。refを使用して、コールバックにコンテキストを提供できます。

参照としてObjective-Cクラスを渡せるようにしたいと思います。したがって、問題は次のとおりです。

NSObjectをvoid*にキャストするにはどうすればよいですか?また、NSObjectとしてvoid*をキャストするにはどうすればよいですか。

前もって感謝します。

4

3 に答える 3

38

このようなことをします:

void func(void *q)
{
    NSObject* o = CFBridgingRelease(q);
    NSLog(@"%@", o);
}

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        NSObject* o = [NSObject new];
        func((void*)CFBridgingRetain(o));
    }
    return 0;
}

CFBridgingRetain()CFBridgingRelease()はコンパイラ属性の周りのマクロであることに注意してください。どちらでもお気軽にご利用ください。APIバリアントは、コードベースでより一般的に使用されており、より明示的で混乱が少ないため、気に入っています。

CFBridgingRetain()によってバランスをとる必要があるオブジェクトを効果的にハード保持しますCFBridgingRelease()また、へのキャストと互換性のあるaCFTypeRefを返すこともあります。 そのハードリテンションを効果的に元に戻すため、有効なスコープ内でのみ有効なままになります。void*CFBridgingRelease()qo

基本的なコールバックには有効ですがvoid *context;、しばらくの間固執しなければならないタイプのものではおそらくそうではないでしょう。そのために:

void callback(void *context)
{
    // grab an ARC aware reference without impacting hard-retain
    NSObject* o = (__bridge NSObject *)(context);
    NSLog(@"%@", o);
}

void freeContext(void *context)
{
    // release the hard-retain
    CFBridgingRelease(context);
}

Xcodeは、キャスト/API呼び出しを省略した場合に何をすべきかを正確に提案するのに非常に優れていることに注意してください。それは、それぞれの代替ソリューションの意味を説明しています(私は、頭の中でまっすぐに保つことができるまで、これに大きく依存していました)。

于 2012-10-16T16:36:36.953 に答える
8

ARCを使用していると思います。電話をかけるときにこのようなものを使用できますmyFunction

id ref = ...; // your Objective-C object
myFunction(callback, (__bridge_retained void *) ref);

コールバックでは、所有権を元に戻す必要があります。

void callback(void* refPtr) {
    id refObj = (__bridge_transfer id) refPtr;
}

必要に応じて、オブジェクトタイプに置き換えidます。

于 2012-10-16T14:23:57.500 に答える
1

回答:決して。void *は任意のポインタ型と暗黙的に互換性があるため、型のポインタid(のエイリアスstruct objc_object *)であるオブジェクトがある場合は、キャストせずに、voidポインタが必要な場所にオブジェクトを渡すことができます。例:

// this is the declaration of the callback function:
void callback(void *context);

// then you can call it like this:
SomeClass *obj = [[SomeClass alloc] init];
callback(obj);
于 2012-10-16T14:09:22.933 に答える