我希望有人能幫助我與此有關。我正在努力尋找一個應該是一個簡單問題的答案。順便說一句,這是我多年使用c和c#之後的第一個主要obj-c項目,所以請隨時指出我失敗的事情。內存分配,釋放和NSURLConnection的在iPhone應用程序
我設計的的照片專輯加載到一個UIScrollView一個iPhone應用程序。它也有一個隨機圖像功能,它使用相同的過程,但只顯示單個圖像。它的工作原理是這樣的:
- 閱讀一個外部XML提要(存儲在ruby-on-rails網站上),該提要包含經過解析的照片隨機URL的路徑。
- URL的內容使用NSURLConnection下載到NSData。
- 滾動型被創建並被推
- 子類的UIView allocs一個的UIImageView,allocs與NSData的一個UIImage其中,inits與UIImage的所述的UIImageView和最後添加的ImageView到了UIView。
- 父視圖然後添加了UIView到的UIScrollView,然後將其推到前面。需要下一個隨機圖像時當
此過程再次發生。它在顯示整個圖像相冊時也使用相同的過程,除了幾個UIViews被添加到UIScrollView。
問題是,儘管在適當的情況下使用release和delloc,但活動工具指示NSURLConnection和UIImage使用的內存在下一圖像請求時未從內存中釋放。通過將應用程序構建到iPhone上可以進一步證明這一點。連續請求多個圖像會導致應用程序崩潰,這可能是由內存消耗造成的。
下面是一些代碼因爲我無法將整個項目完成後,由於合同協議。
URLDownload類(使用數據下載)
@implementation URLDownload
-(NSData *)GetURL:(NSURL *)strURL
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
DataDownload *request = [DataDownload alloc];
request.strURL = strURL;
[request init];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
while (request.isLoading && [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
[pool release];
return [request urlData];
[request release];
}
數據下載類
@implementation DataDownload
@synthesize urlData, connection, strURL, isLoading;
- (id)init
{
if(self = [super init])
{
self.isLoading = YES;
NSURLRequest *dataRequest = [NSURLRequest requestWithURL:self.strURL
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:60];
/* establish the connection */
self.connection = [[NSURLConnection alloc]
initWithRequest:dataRequest
delegate:self
];
if (connection == nil) {
self.urlData = nil;
} else {
self.urlData = [NSMutableData data];
}
}
return self;
}
- (void)dealloc {
[connection cancel];
[connection release];
[urlData release];
[strURL release];
[super dealloc];
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
return nil;
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse*)response
{
[urlData setLength:0];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)incrementalData
{
[self.urlData appendData:incrementalData];
}
-(void)connectionDidFinishLoading:(NSURLConnection*)connection
{
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
self.isLoading = NO;
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
self.isLoading = NO;
}
@end
ImageView的子類
@implementation ImageView
@synthesize strURL, imvImageView, image, currentlyRotated, imgOptionsView, startDate;
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.imvImageView = [UIImageView alloc];
if (self.strURL != nil){
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
NSData *datImageData = [NSData dataWithContentsOfURL: [NSURL URLWithString:self.strURL]];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
self.image = [UIImage imageWithData: datImageData];
CGSize imgSize = image.size;
CGFloat fltWidth = imgSize.width;
CGFloat fltHeight = imgSize.height;
[imvImageView initWithImage:image];
// If landscape rotate image
if (fltWidth > fltHeight){
imvImageView.frame = CGRectMake(-80.0, 80.0, 480.0, 320.0);
CGAffineTransform rotate = CGAffineTransformMakeRotation(-1.57079633);
[imvImageView setTransform:rotate];
self.currentlyRotated = YES;
}else{
imvImageView.frame = CGRectMake(0.0, 0.0, 320.0, 480.0);
self.currentlyRotated = NO;
}
[image release];
}else{
self.image = [UIImage alloc];
[imvImageView initWithImage:image];
[image release];
}
[self addSubview:imvImageView];
}
[imvImageView release];
return self;
}
- (void)drawRect:(CGRect)rect {
// Drawing code
}
- (void)dealloc {
[strURL release];
[imvImageView release];
[image release];
[imgOptionsView release];
[startDate release];
[super dealloc];
}
的是如何被顯示的圖像的示例代碼
- (void)displayImage:(NSString *)strURL {
NSString *strFullURL = @"http://www.marklatham.co.uk";
strFullURL = [strFullURL stringByAppendingString:strURL];
self.scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 480.0)];
[scroller setContentSize:CGSizeMake(320.0, 540.0)];
[self.view addSubview:scroller];
CGRect rect = CGRectMake(0.0, 0.0, 320.0, 480.0);
self.imageView = [ImageView alloc];
imageView.strURL = strFullURL;
[imageView initWithFrame:rect];
[scroller addSubview:imageView];
[scroller release];
[imageView release];
}
本
下圖顯示了所有的分配來說明發生了什麼。 1顯示啓動時的alloc,2顯示第一個圖像加載後,3顯示第二個圖像後。
http://www.gretanova.com/misc/iphone/1.png & 2.png & 3.png
謝謝大家, 李
退房這種類似的問題後: http://stackoverflow.com/questions/1632168/當通話釋放 - 上NSURLConnection的委託方 – 2009-10-28 21:27:49