2009-10-28 1 views
0

Я надеюсь, что кто-то может мне помочь. Я изо всех сил пытаюсь найти ответ на вопрос, который должен быть простым. Кстати, это мой первый крупный проект obj-c после многих лет использования c и C#, поэтому не стесняйтесь указывать на то, что я провал.Распределение памяти, выпуск и NSURLConnection в приложении для iPhone

У меня есть приложение для iPhone, предназначенное для загрузки альбома фотографий в UIScrollView. Он также имеет функцию случайного изображения, которая использует тот же процесс, но отображает только одно изображение. Он работает следующим образом:

  1. Прочитайте внешний XML-канал (хранящийся на веб-сайте ruby-on-rails), который содержит путь к случайному URL-адресу после разбора.
  2. Содержимое URL-адреса загружается с использованием NSURLConnection в NSData.
  3. ScrollView создан и толкнул
  4. подклассов UIView ALLOCS в UIImageView, ALLOCS в UIImage с NSData, который inits в UIImageView с UIImage и, наконец, добавляет ImageView в UIView.
  5. Родительское представление затем добавляет UIView в UIScrollView, который затем выдвигается на передний план.

Этот процесс происходит снова, когда требуется следующее случайное изображение. Он также использует тот же процесс при отображении всего альбома изображений, за исключением нескольких UIViews, добавленных в UIScrollView.

Проблема заключается в том, что, несмотря на использование 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]; 

} 

класс DataDownload

@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 &

Спасибо всем, Ли

+0

Проверьте этот же вопрос: http://stackoverflow.com/questions/1632168/ когда для вызова-релиз-на-NSURLConnection-делегата –

ответ

1

Несколько вещей торчат.Например в классе URLDownload вызов [выпуск запроса] никогда не будет достигнут, как размещенный после возвращения заявления

return [request urlData]; 
[request release];