1

SCDynamicStoreContextは次のように定義されています (バージョン 0):

typedef struct {
      CFIndex        version;
      void *         info;
      const void *   (*retain)(const void *info);
      void           (*release)(const void *info);
      CFStringRef    (*copyDescription)(const void *info);
} SCDynamicStoreContext;

を初期化する方法について私が見たさまざまな例( Apple のものSCDynamicStoreContextを含む) はすべて、、、およびフィールドをに設定しましたが、これらのフィールドが何のためにあるのか疑問に思っています。retainreleasecopyDescriptionNULL

たとえば、オブジェクトが である場合にand関数を渡さないことの意味は何ですか?retainreleaseinfoNSObject

機能は何のcopyDescriptionために使用されますか?

4

1 に答える 1

4

SCDynamicStoreたとえば、によって作成されたオブジェクトの有効期間SCDynamicStoreCreate()は不確定です。完全にリリースされるまで存続します。存続している限り、提供されたコールバックを呼び出すことができます。infoその場合、コンテキストで提供されたポインターを渡します。動的ストア オブジェクトが存続している限り、ポインターが有効なままであることを確認する手順を実行しないと、infoポインターが無効になる可能性があります。infoポインタが無効になった後にコールバックがアクセスすると、コールバックがクラッシュまたは誤動作を引き起こす可能性があります。

コンテキストのretainおよび関数ポインターにより、フレームワークは、ポインターが有効である必要がある期間releaseを知る手段を提供できます。明らかに、動的ストアが作成された時点でinfo有効 (または) である必要があります。さらに、関数への呼び出しが対応する関数への呼び出しによってバランスが取れていないNULL限り、それは有効であり続ける必要があります。retainrelease

保持関数と解放関数を提供しない場合、infoポインターは永続的に、または少なくとも動的ストア オブジェクトが有効である限り有効である必要があり、それを保証する責任があります。他のどの API が動的ストア オブジェクトを保持するかを常に知っているとは限らないため、これはやや難しい場合があります。すべての実行ループからソースを削除しても、その時点でソースが完全に解放されるとは限りませんが、実行ループ ソースが実行ループでスケジュールされている限り、確実に存続します。

このcopyDescription関数は、デバッグ出力を強化する手段です。たとえば、特定の状況下では、フレームワークがログ メッセージを書き込むことがあります。状況に遭遇した動的ストア オブジェクトを記述しようとします。クライアントにとって最も意味のある方法でそれを行うためにinfo、コンテキストからの説明を含めることができます。関数がない場合copyDescription、ポインタ値を記録することが最善の方法です。もしそうなら、その関数によって提供されるどんな記述でも書くことができます。

CFRetain()偶然ではありませんが、3 つの関数ポインタのシグネチャは、 、CFRelease()、およびのシグネチャと一致しCFCopyDescription()ます。したがって、infoが Core Foundation オブジェクトまたは Cocoa オブジェクトである場合 (NSObjectは に無料でブリッジされているためCFTypeRef)、これらの関数をコンテキストで指定すると、すべてが期待どおりに動作します。

于 2014-07-20T18:31:17.207 に答える