一种方法是添加第二个功能
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
然后我测试了 release,稍微改变了测试,添加了一个设置在的__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:
在第二个函数autoreleaseBufferOfLength
中具有创建 NSData 对象并将其放置在自动释放池中的效果。
注意:这不是一个好主意。正如@ughoavgfhw 在他的回答中所描述的那样,通过排空自动释放池来实现malloc
'd的最佳方法free
是添加一个在没有 ARC 的情况下构建的文件(使用)。-fno-objc-arc
然而,这种方法可能会引起一些兴趣。