1つのアプローチは、2番目の関数を追加することです
NSData *autoreleaseBufferOfLength(void *bytes, NSUInteger length)
{
return [NSData dataWithBytesNoCopy:bytes length:length freeWhenDone:YES];
}
この関数は、自動解放されたNSData
オブジェクトを返します。
バッファを返す関数からこの関数を呼び出します
void *getAutoreleasedBuffer(NSUInteger length)
{
void *buffer = malloc(length);
if (buffer) {
autoreleaseBufferOfLength(buffer, length);
}
return buffer;
}
NSData
から返されたオブジェクトautoreleaseBufferOfLength
は自動解放プールにあるため、自動解放プールが空になるとバッファーが解放されます(でNSData
作成されたオブジェクトのautoreleaseBufferOfLength
割り当てが解除されるため)。
この関数を使用してこれをデバッグするためにテストしましたmain
int main(int argc, const char * argv[])
{
@autoreleasepool {
__unused void * buffer = autoreleasingBuffer(32);
NSLog(@"%s:exiting @autoreleasepool block", __PRETTY_FUNCTION__);
}
NSLog(@"%s:exited @autoreleasepool block", __PRETTY_FUNCTION__);
return 0;
}
-[NSConcreteData dealloc]
アクションでシンボリックブレークポイントを追加し、po @"deallocating NSConcreteData"
「評価後に自動的に続行する」をチェックします。これが出力でした
[53030:303] int main(int, const char **):exiting @autoreleasepool block
(NSString *) $0 = 0x0000000100300530 deallocating NSConcreteData
[53030:303] int main(int, const char **):exited @autoreleasepool block
次に、リリースをテストし、テストを少し変更し、で設定された__weak
グローバル変数を追加しました。g_data
autoreleaseBufferOfLength
__weak NSData *g_data = nil;
NSData *autoreleaseBufferOfLength(void *bytes, NSUInteger length)
{
return (g_data = [NSData dataWithBytesNoCopy:bytes length:length freeWhenDone:YES]);
}
メインのログインを変更します。
int main(int argc, const char * argv[])
{
@autoreleasepool
{
__unused void * buffer = autoreleasingBuffer(32);
NSLog(@"%s:exiting @autoreleasepool block; g_data = %@", __PRETTY_FUNCTION__, g_data);
}
NSLog(@"%s:exited @autoreleasepool block; g_data = %@", __PRETTY_FUNCTION__, g_data);
return 0;
}
リリース用にビルドして実行すると、次のようになります。
[53934:707] int main(int, const char **):exiting @autoreleasepool block; g_data = 00000000 00000070 00000000 00000070 10000000 00000000 00000000 00000000>
[53934:707] int main(int, const char **):exited @autoreleasepool block; g_data = (null)
これらのテストは、への呼び出しをdataWithBytesNoCopy:length:freeWhenDone:
2番目の関数でラップするとautoreleaseBufferOfLength
、NSDataオブジェクトを作成し、それを自動解放プールに配置する効果があることを示しています。
注:これは良い考えではありません。malloc
自動解放プールのドレインによって'dである'dを実現する最良の方法は、@ ughoavgfhwが彼の回答で説明しているように、free
(を使用して)ARCなしでビルドされたファイルを追加することです。-fno-objc-arc
それにもかかわらず、このアプローチはある程度興味深いかもしれません。