問題が何度も報告されていることは知っていますが、ほとんどすべての回答が非ARCプロジェクトに関するものであり、私は何日も立ち往生しています。私は多くのフォーラムや記事を見てきました。ここで助けが得られるといいのですが。
私は非同期のNSURLConnectionリクエストを使用して、IOS 5で、ARCを使用して次のように画像をダウンロードします(「iPadプログラミングの学習」という本から着想を得たコード)。
-(void) dowloadImageAtURL:(NSURL *)URL
{
if (URL)
{
self.image = nil;
self.receivedData = [[NSMutableData alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:URL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request // Building asynchronous connection
delegate:self
startImmediately:NO]; // This is the key to not run the connection synchronous
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; // We use the current loop but it will still be asynchronous
// because of the mode added to the current loop
[connection start];
request = nil;
}
}
#pragma marks - NSURLConnection delegate Methods
/*
Called when the web server responds to the request.
When the method is called, the receivedData property is reset with a length of zero, clearing any previously stored data.
This ensures that only the data received from the final request is captured (see NSURLConnectionDelegate reference).
*/
- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[self.receivedData setLength:0];
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
sharedCache = nil;
connection = nil;
}
/*
Called when data is received from the network. The method can be called a multiple times during a single request.
The data is appended to the data already stored in the receivedData property.
*/
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.receivedData appendData:data];
}
/*
Called after the request has completed all data and all data has been received. This method converts
the data stored to a UIImage object.
*/
- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
self.image = [UIImage imageWithData:self.receivedData];
self.receivedData = nil;
connection = nil;
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
sharedCache = nil;
// Here we post a notification to the observer
[[NSNotificationCenter defaultCenter] postNotificationName:@"com.perfectmemory.famille.imageupdated" object:self];
}
/*
Called if an error is detected at any time during the download process.
*/
- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
self.receivedData = nil;
connection = nil;
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
sharedCache = nil;
// Here we post a notification to the observer
[[NSNotificationCenter defaultCenter] postNotificationName:@"com.perfectmemory.famille.imageupdated" object:self];
}
このコードを実行すると、ダウンロードは正常に機能しますが、XCodeインスツルメントにリークが見られます
- URLConnectionLoader :: LoaderConnectionEventQueue
- URLConnection :: scheduleWithRunLoop
- CFURLResponse
URLConnectionInstanceData
キャッシュのクリアなど、問題の修正を試みるために次のヘルプを使用しましたが、成功しませんでした。
- NSURLConnectionのリーク-なぜですか?
- http://www.friendlydeveloper.com/2010/04/successfully-working-around-the-infamous-nsurlconnection-leak/
- NSURLConnectionリーク?
また、関係する各デリゲートメソッドの接続を次のように解放しようとしました。
connection = nil
しかし、それでも成功しません。何が起こっているのか本当にわかりません。未リリースのオブジェクトが見つかりません。手伝っていただけませんか ?この非同期ダウンロードリクエストは非常に一般的だと思うので、非常にイライラします。
よろしくお願いします。