有人能告诉我为什么以下代码会在ARC下泄漏内存吗?我用仪器对它们进行了测试,它告诉我它们会导致内存泄漏,但我不知道如何修复它们?
static inline NSString* cachePathForKey(NSString* directory, NSString* key) {
return [directory stringByAppendingPathComponent:key]; //leak
}
@property (nonatomic,strong) NSMutableData *postBody;
if (![self postBody]) {
[self setPostBody:[NSMutableData data]]; //leak
}
另一个问题:这些工具向我显示“所有堆分配”和“所有匿名虚拟机”直播字节。例如,如果一个应用程序占用超过80M(例如),它将崩溃。那么80M意味着所有堆分配或两者?
更新
正如我在下面的一条评论中所提到的,我现在正致力于将非ARC ASIHttpRequest更改为ARC模式。泄漏来了。以ASIInputStream为例:
+ (id)inputStreamWithData:(NSData *)data request:(ASIHTTPRequest *)theRequest {
ASIInputStream *theStream = [[self alloc] init]; //leak 42%
[theStream setRequest:theRequest];
NSInputStream *is = [NSInputStream inputStreamWithData:data]; //leak 58%
[theStream setStream:is];
return theStream;
}
答案 0 :(得分:0)
这是一个黑暗中的镜头,但在C函数上,你可以尝试这个
__attribute__((ns_returns_autoreleased))
static inline NSString* cachePathForKey(NSString* directory, NSString* key) {
return [directory stringByAppendingPathComponent:key]; //leak
}
比照。 Clang docs了解更多信息。您也可以尝试摆脱static inline
,看看是否有帮助。
答案 1 :(得分:0)
如果您正在混合使用ARC和非ARC代码,那么在没有看到全局的情况下很难建议您。我不知道你的技术水平是什么,但我会引导新手远离尝试这种混合。
我将一段代码放入一个新的 Empty iOS应用程序中测试;看起来像这样:
这是我完整的AppDelegate实现,除了不断运行cachePathForKey
函数之外什么都不做。
#import "AppDelegate.h"
@implementation AppDelegate
static inline NSString* cachePathForKey(NSString* directory, NSString* key) {
return [directory stringByAppendingPathComponent:key]; //leak
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
while (YES) {
@autoreleasepool {
NSString *s = cachePathForKey(@"/my/fake/dir", @"key");
}
}
return YES;
}
@end
我运行它Xcode,Product>配置文件,当仪器启动时,我选择Memory>泄漏。它没有发现任何问题。您可以尝试从头开始构建,看看您是否能够找到问题。
另一种技术是制作项目的副本(或分支;我强烈建议版本控制,尤其是git
)。然后开始剥离代码,直到你得到仍然泄漏的极少量代码。然后你可以在某处发布该代码; github很常见,无论是作为一个小块 - gist - 还是作为一个完整的Xcode项目。
无论哪种方式,自上而下或自下而上,这都是令人沮丧的,也是艰苦的,就像一个艰难的科学发现,或一个难以捉摸的警方调查。但是,坚持不懈地解决这些问题是软件开发人员的重要组成部分。这里有一个非常有用的社区。祝你好运。