我在iOS应用程序中有一个场景,其中操作非常大的Nsstring实例(HTTP响应,高达11MB)导致多个大型中介一次在内存中,因为我调用的SDK方法返回新的自动释放实例.在这里采取的最佳方法是什么?
例如,假设largeString是一个自动释放的Nsstring实例:
NSArray *partsOfLargeString = [largeString componentsSeparatedByString:separator];
for (Nsstring *part in partsOfLargeString) {
Nsstring *trimmedPart = [part stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSData *data = [trimmedPart dataUsingEncoding:NSUTF8StringEncoding];
}
如果componentsSeparatedByString或stringByTrimmingCharactersInSet有非自动释放的等价物会很棒,但我不打算自己实现这些.
据我所知,没有办法“强制”释放已经添加到自动释放池中的对象.我知道我可以在这里创建和使用我自己的自动释放池,但我想要非常精细,并且围绕单个语句自动释放池肯定不是一种非常可扩展的方法.
任何建议都非常感谢.
解决方法
正如Bill所说,我首先尝试为每个循环迭代设置一个自动释放池,例如:
for (Nsstring *part in partsOfLargeString) {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
Nsstring *trimmedPart = [part stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSData *data = [trimmedPart dataUsingEncoding:NSUTF8StringEncoding];
…
[pool drain];
}
或者,如果您使用的是最近的编译器:
for (Nsstring *part in partsOfLargeString) {
@autoreleasepool {
Nsstring *trimmedPart = [part stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSData *data = [trimmedPart dataUsingEncoding:NSUTF8StringEncoding];
…
}
}
如果仍然无法接受并且您确实需要以更精细的方式发布对象,则可以使用以下内容:
static inline __attribute__((ns_returns_retained))
id BICreateDrainedPoolObject(id (^expression)(void)) {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
id object = expression();
[object retain];
[pool drain];
return object;
}
#define BIOBJ(expression) BICreateDrainedPoolObject(^{return (expression);})
它会计算表达式,保留其结果,释放任何辅助自动释放的对象并返回结果;然后:
for (Nsstring *part in partsOfLargeString) {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
Nsstring *trimmedPart = BIOBJ([part stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]);
NSData *data = BIOBJ([trimmedPart dataUsingEncoding:NSUTF8StringEncoding]);
[trimmedPart release];
// do something with data
[data release];
…
[pool drain];
}
请注意,由于函数返回一个保留对象,因此您负责释放它.你可以控制何时这样做.
随意为功能和宏选择更好的名称.可能存在一些应该处理的极端情况,但它应该适用于您的特定示例.欢迎提出建议!