Ios NSURL连接内存泄漏

Ios NSURL连接内存泄漏,ios,objective-c,memory-management,memory-leaks,nsurlconnection,Ios,Objective C,Memory Management,Memory Leaks,Nsurlconnection,我运行instruments工具,发现一些内存泄漏,我不知道如何处理。我在用弧 这是我的代码: + (MARequest *)requestImageThumb:(NSString *)imageName object:(NSInteger)objectId { NSString* urlString = [NSString stringWithFormat:@"%@/%@", kBaseImageThumbURL, imageName];

我运行instruments工具,发现一些内存泄漏,我不知道如何处理。我在用弧

这是我的代码:

+ (MARequest *)requestImageThumb:(NSString *)imageName
                      object:(NSInteger)objectId {
   NSString* urlString = [NSString stringWithFormat:@"%@/%@", kBaseImageThumbURL, imageName];

   LogTrace(@"Creating image thumb request for file %@", imageName);

   //Here starts the leak!!
   return [MARequest createWithURL:[NSURL URLWithString:urlString]
                           type:REQUEST_TYPE_GET_IMAGE];
}


+ (MARequest *)createWithURL:(NSURL *)url
                    type:(NSInteger)type {

   MARequest* r = [[MARequest alloc] init];

   r.url = url;
   r.requestType = type;
   r.responseData = [[NSMutableData alloc] init];
   r.connection = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:r.url]
                                               delegate:r
                                       startImmediately:NO];

   return r;
}
这是我的大使馆

#pragma mark - NSURLConnectionDelegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
   LogTrace(@"request %@: didReceiveResponse", self.url);
   [self.responseData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
   LogTrace(@"request %@: didReceiveData, %d bytes", self.url, data.length);

   [self.responseData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
   LogTrace(@"request %@: didFailWithError: %@", self.url, [error description]);

   self.connection = nil;
   self.failed = YES;

[self invokeAction];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
   LogTrace(@"request %@: connectionDidFinishLoading, %d bytes", self.url, [self.responseData length]);
   self.connection = nil;

   [self invokeAction];
}
编辑:

我现在把代码改成了这个,但遗憾的是它仍然给我带来了内存泄漏

+ (MARequest *)requestImageThumb:(NSString *)imageName
                      object:(NSInteger)objectId {
    NSString* urlString = [NSString stringWithFormat:@"%@/%@", kBaseImageThumbURL, imageName];

    LogTrace(@"Creating image thumb request for file %@", imageName);

    return [MARequest requestWithURL:[NSURL URLWithString:urlString]
                           type:REQUEST_TYPE_GET_IMAGE];
}

+ (MARequest *)requestWithURL:(NSURL *)url
                    type:(NSInteger)type {

   MARequest* r = [[MARequest alloc] init];

   r.url = url;
   r.requestType = type;
   r.responseData = [[NSMutableData alloc] init];
   r.connection = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:r.url]
                                               delegate:r
                                       startImmediately:NO];



   return r;
}

编辑:更改后,泄漏的解释如下:

您的
GFRequest
对象和
NSURLConnection
对象之间存在循环依赖关系,因此无法正确解除分配这两个对象。实际上,您正在将
GFRequest
的连接属性设置为
NSURLConnection
实例:

   r.connection = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:r.url]
同时也使
r
成为该
nsurl连接的代表

             delegate:r
结果就是这样,这导致了依赖循环

不过,我认为没有一种简单的方法可以打破依赖关系,并保持当前的设计

您可以简单地避免将连接存储在请求中,或者不能将请求用作连接的委托。可能的话,你应该考虑子类<代码> NSURLCONTION/CONT>的可能性,并将其作为自己的委托。< /P> 旧答案:

外部方法名称与内部方法名称不匹配:

+ (MARequest *)requestImageThumb:(NSString *)imageName
…
   return [MARequest createWithURL:[NSURL URLWithString:urlString]
对于静态分析器,它们对于对象所有权具有不同的语义

将第一个替换为:

+ (MARequest *)createRequestImageThumb:(NSString *)imageName
   return [MARequest requestWithURL:[NSURL URLWithString:urlString]
或第二个带有:

+ (MARequest *)createRequestImageThumb:(NSString *)imageName
   return [MARequest requestWithURL:[NSURL URLWithString:urlString]

取决于哪种语义适合您的情况。

听起来像是您使用单词
create
启动了该方法,它向ARC指示它将返回一个保留计数为1的对象。换句话说,
create
表示调用方将负责在对象完成时释放该对象

但是,您可以直接在另一个方法中返回此对象,该方法不以
create
开头。这表明,如果第二个方法的调用方希望保留对象,那么它是否应该保留该对象

这里有冲突,我认为ARC不知道该怎么办。它是否应该释放该对象

如果您将
+createWithURL:type:
重命名为
+requestWithURL:type:
,这应该可以解决问题,因为
+requestWithURL:type:
将返回一个自动释放的对象,这正是
+requestImageThumb:object:
希望返回的对象


或者,将
+requestImageThumb:object:
重命名为
+createRequestWithImageThumb:object:
以明确要求
+createRequestWithImageThumb:object:
返回保留的对象,该对象是从
+createWithURL:type:

获取的,非常感谢您,很遗憾,我仍然有漏洞,请查看我的编辑!非常感谢,这是有道理的,但它仍然给我一个漏洞,请看我的编辑:)请再次显示静态编译器输出…我添加了两个截图,希望这将帮助你!你能给我看一下GFRrequest接口定义吗?顺便说一句,你注意到泄漏不是原来的地方。。。