我希望有人可以帮助我解决这个问题。我正在努力寻找应该是一个简单问题的答案。顺便说一句,这是我使用 c 和 c# 多年后的第一个主要 obj-c 项目,所以请随时指出我失败的地方。
我有一个 iPhone 应用程序,旨在将相册加载到 UIScrollView 中。它还具有随机图像功能,该功能使用相同的过程,但仅显示单个图像。它是这样工作的:
- 读取外部 XML 提要(存储在 ruby-on-rails 网站上),其中包含解析后照片的随机 url 的路径。
- 使用 NSURLConnection 将 URL 的内容下载到 NSData。
- 创建并推送 ScrollView
- 子类 UIView 分配一个 UIImageView,分配一个带有 NSData 的 UIImage,用 UIimage 初始化 UIImageView,最后将 imageview 添加到 UIView。
- 然后,父视图将 UIView 添加到 UIScrollView,然后将其推到前面。
当需要下一个随机图像时,此过程再次发生。除了向 UIScrollView 添加了几个 UIView 之外,它在显示整个图像专辑时也使用相同的过程。
问题是,尽管在适当的情况下使用了 release 和 delloc,但活动工具指示 NSURLConnection 和 UIImage 使用的内存在请求下一个图像时没有从内存中释放。将应用程序构建到 iPhone 上进一步证明了这一点。连续请求多个图像会导致应用程序崩溃,这可能是由于内存消耗造成的。
以下是一些代码,因为由于合同协议,我无法发布整个项目。
URLDownload 类(使用 DataDownload)
@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 显示启动时分配,2 显示加载第一个图像后,3 显示第二个图像后。
http://www.gretanova.com/misc/iphone/1.png & 2.png & 3.png
谢谢大家,李