Управление памятью в UITableView и UINavigationController - PullRequest
1 голос
/ 06 февраля 2012

Обновления

Я обновил коды и обнаружил, что могу либо nil iconDownLoader, либо загрузить Array, но не оба из них.

Я думал, что nil в unload отличается от release в dealloc?А self.xxx = nil нужен?И я обновил коды.Это работает хорошо (хотя это не освобождает всю память), но я действительно не понимаю это.

Не могли бы вы объяснить, почему?Спасибо


Я много искал, но все еще не могу решить эту проблему управления памятью.Надеюсь, кто-нибудь может помочь мне исправить это и понять принцип.

У меня есть UIViewController, в котором есть UITableView.В таблицу загружаются пользовательские ячейки и изображения.Он потребляет много памяти каждый раз и не освобождает память после того, как я popViewControllerAnimated.Память увеличится до 200 м после нескольких нажатий и нажатия на viewController.

Вот некоторые коды, любая помощь будет оценена.

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

#pragma mark - View lifecycle

- (void)viewDidUnload
{
    self.newsArray = nil;
    self.newsTableView = nil;
    self.indicatorView = nil;
//  self.iconDownLoader = nil;
    self.downloadArray = nil;

    [super viewDidUnload];
}

... 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"NewsCellIdentifier";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"NewsTableViewCell" owner:self options:nil];
        cell = self.newsTableViewCell;
        self.newsTableViewCell = nil;
    }

    // read from newsModel
    NewsModel *news = [newsArray objectAtIndex:indexPath.row];

    UILabel *label;
    label = (UILabel *)[cell viewWithTag:10];
    label.text = [NSString stringWithString:news.title];
    label = nil;
    label = (UILabel *)[cell viewWithTag:11];
    label.text = [NSString stringWithString:news.description];
    UIImageView *imageView = (UIImageView *)[cell viewWithTag:12];
    imageView.image = news.image;

    if (news.image == nil)
    {
        imageView.image = [UIImage imageNamed:IconPlaceHolder];

        IconDownLoader *iconDownLoader = [[IconDownLoader alloc] init];
        iconDownLoader.url = news.imageUrl;
        iconDownLoader.delegate = self;
        iconDownLoader.indexPath = indexPath;
        if (appDelegate.ip4 == YES)
        {
            iconDownLoader.width = 300;
            iconDownLoader.height = 150;
        }
        else
        {
            iconDownLoader.width = 150;
            iconDownLoader.height = 75;
        }
        [downloadArray addObject:iconDownLoader];
        [iconDownLoader start];
    }
    return cell;
}

#pragma mark - IconDownLoaderDelegate

- (void)iconDownLoadFinsh:(NSData *)imageData row:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [newsTableView cellForRowAtIndexPath:indexPath];
    UIImageView *imageView = (UIImageView *)[cell viewWithTag:12];
    if (imageData != 0)
    {
        imageView.image = [UIImage imageWithData:imageData];
    }
    else
    {
        imageView.image = [UIImage imageNamed:@"icon57"];
    }
    NewsModel *newsModel = [newsArray objectAtIndex:indexPath.row];
    newsModel.image = [UIImage imageWithData:imageData];
}

А это IconDownloader

#import "IconDownLoader.h"
#import "ASIHTTPRequest.h"

@implementation IconDownLoader

@synthesize delegate = _delegate;
@synthesize url = _url;
@synthesize indexPath = _indexPath;
@synthesize width = _width;
@synthesize height = _height;
@synthesize request = _request;

- (void)start {

    NSString *originalString = @"width=%s&height=%s";
    NSString *newString = [NSString stringWithFormat:@"width=%d&height=%d&type=jpg", self.width, self.height];

    NSString *resizedURL = [self.url stringByReplacingOccurrencesOfString:originalString withString:newString];

    NSURL *url = [NSURL URLWithString:[resizedURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    _request = [ASIHTTPRequest requestWithURL:url];
    if (_indexPath) {
        _request.userInfo = [NSDictionary dictionaryWithObject:_indexPath forKey:@"indexPath"];
    }
    [_request setDelegate:self];
    [_request startAsynchronous];
}

- (void)requestFinished:(ASIHTTPRequest *)request {

    NSInteger statusCode = request.responseStatusCode;
    switch (statusCode) {
        case 401: // Not Authorized: either you need to provide authentication credentials, or the credentials provided aren't valid.
            break;

        case 200: {
            NSData *responseData = [request responseData];
            if (!responseData) {
                UIAlertView *alertView;
                alertView = [[UIAlertView alloc] initWithTitle:@"Oops" message:[NSString stringWithFormat:@"Download failed in row %d", _indexPath.row] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
                return;
            }
            [_delegate iconDownLoadFinsh:responseData row:[request.userInfo objectForKey:@"indexPath"]];
        }
            break;

        case 304: // Not Modified: there was no new data to return.
            break;
        case 400: // Bad Request: your request is invalid, and we'll return an error message that tells you why. This is the status code returned if you've exceeded the rate limit
            break;
        case 403: // Forbidden: we understand your request, but are refusing to fulfill it.  An accompanying error message should explain why.
            break;

        case 404: // Not Found: either you're requesting an invalid URI or the resource in question doesn't exist (ex: no such user). 
        {
            UIAlertView *alertView;
            alertView = [[UIAlertView alloc] initWithTitle:@"Oops" message:@"Classical 404, please contact with your administer" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        }
            break;
        case 500: // Internal Server Error: we did something wrong.  Please post to the group about it and the Weibo team will investigate.
        case 502: // Bad Gateway: returned if Weibo is down or being upgraded.
        case 503: // Service Unavailable: the Weibo servers are up, but are overloaded with requests.  Try again later.
        {
            UIAlertView *alertView;
            alertView = [[UIAlertView alloc] initWithTitle:@"Oops" message:@"503 error, service unavailable" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        }
        default:{

        }
    }
}

- (void)dealloc {
    if (_request != nil) {
        [_request clearDelegatesAndCancel];
    }
}

@end

1 Ответ

3 голосов
/ 06 февраля 2012

Вы не выпускаете IconDownLoader.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...