gpt4 book ai didi

ios - viewDidUnload 中的内存管理——我应该将数组和对象都清零吗?

转载 作者:行者123 更新时间:2023-11-28 23:06:41 25 4
gpt4 key购买 nike

我有一个表格 View 可以从互联网加载新闻。我并试图清零 viewDidUnload 中的所有属性。

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

[super viewDidUnload];
}

每次应用程序在 viewDidUnload 中崩溃。如果我评论 self.iconDownLoader = nil;,那就没问题了。那么谁能告诉我为什么会这样呢?谢谢你。

--------------------NewsViewController.m-------------------- ------

//
// NewsViewController.m
//
// Created by on 18/01/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "NewsViewController.h"
#import "ASIHTTPRequest.h"
#import "SBJson.h"
#import "NewsModel.h"
#import "NewsDetailViewController.h"

#define kCustomRowCount 6
#define IconPlaceHolder @"Spinner"

@implementation NewsViewController

@synthesize appDelegate, newsTableViewCell, newsTableView, indicatorView;
@synthesize iconDownLoader, newsArray, downloadArray;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {

// setup appDelegate
self.appDelegate = (SydneyAppDelegate *)[[UIApplication sharedApplication] delegate];

// initial arrays
self.newsArray = [[NSMutableArray alloc] init];
self.downloadArray = [[NSMutableArray alloc] init];
}
return self;
}

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

#pragma mark - View lifecycle

- (void)viewDidLoad
{
[super viewDidLoad];

if(self.appDelegate.reachable) {
[self getNews];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No Connection" message:@"No Internet connection. Please try again later." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
}
}

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

[super viewDidUnload];
}

#pragma mark - ASIHTTPRequest

- (void) getNews
{
NSURL *url = [NSURL URLWithString:@"http://ferrarimaseratisydney.com/api/getPublicNews.html"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request startAsynchronous];
}

- (void) requestFinished:(ASIHTTPRequest *)request
{
NSString *responseString = [request responseString];
NSArray *json = [responseString JSONValue];

for (id aNewsInJson in json)
{
NewsModel *aNews = [[NewsModel alloc] initWithJson:aNewsInJson];
[self.newsArray addObject:aNews];
}

[self.indicatorView removeFromSuperview];

[self.newsTableView reloadData];
}

- (void) requestFailed:(ASIHTTPRequest *)request
{
NSError *error;
error = [request error];
}

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];

// Navigation logic may go here. Create and push another view controller.
NewsDetailViewController *newsDetailViewController = [[NewsDetailViewController alloc] init];

// transform news array
newsDetailViewController.news = [self.newsArray objectAtIndex:indexPath.row];

// Pass the selected object to the new view controller.
[self.navigationController pushViewController:newsDetailViewController animated:YES];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.newsArray count];
}

- (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 = [self.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];

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

#pragma mark - IconDownLoaderDelegate

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

UITableViewCell *cell = [self.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 = [self.newsArray objectAtIndex:indexPath.row];
newsModel.image = [UIImage imageWithData:imageData];
}

@end

------------------------IconDownLoader.m-------------------- -

//
// IconDownLoader.m
//
// Created by on 24/11/11.
// Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#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;

default:{

}
}
}

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

@end

最佳答案

通常在 viewDidUnload 中,您应该只释放并清零对您拥有的 nib 对象的所有引用。

也就是说,如果 model 对象占用大量内存,您也可以在 viewDidUnload 中销毁它们。你应该记住 viewDidUnloadviewDidLoad 的对应物,所以一个好的经验法则是只销毁你在 viewDidUnload 中创建的那些对象viewDidLoad。您还应该记住,viewDidUnload 不会在 View Controller 被释放时被调用——只有当它的 View 被释放时才会被调用。

在你的情况下,我不会发布 newsArraydownloadArray 只是因为你在 init... 中创建它们。我只会向他们发送 removeAllObjects

至于崩溃,每次单元格需要图像时,您都会创建一个新的共享图标下载器,这有点尴尬。如果您确实需要共享下载器实例,则不应为每个单元重新创建它。看起来您想将创建的所有下载器保存在一个 ivar 数组中,因为每个下载器都是一次性的并且负责加载单个图像。

关于ios - viewDidUnload 中的内存管理——我应该将数组和对象都清零吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9187949/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com