gpt4 book ai didi

iphone - 用于内存管理的 dealloc 与 ViewDidDissapear

转载 作者:行者123 更新时间:2023-12-01 17:24:11 25 4
gpt4 key购买 nike

我有一些解析从互联网下载的 xml 的 View 。

仪器泄漏工具告诉我,当我在 dealloc 方法中释放数据成员时有泄漏,但在我放 [objectname release]; 时没有。里面 viewDidDissapear .

这是大罪吗?

来自 c/c++ 背景,我发现 obj-c 内存管理非常困惑!

编辑:这是代码:

#import "SuggestedFriendList.h"

@implementation SuggestedFriendList

@synthesize maincell,nationalityimageview, subjectimageview, accommodationimageview;

- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
{
currentElement = [[elementName copy] autorelease];
if ([elementName isEqualToString:@"shared"])
{
tshared = [[NSMutableString alloc] init];
}

if ([elementName isEqualToString:@"fullname"])
{
tfullname = [[NSMutableString alloc] init];
}

if ([elementName isEqualToString:@"nationality"])
{
tnationality = [[NSMutableString alloc] init];
}

if ([elementName isEqualToString:@"subject"])
{
tsubject = [[NSMutableString alloc] init];
}

if ([elementName isEqualToString:@"accommodation"])
{
taccommodation = [[NSMutableString alloc] init];
}

if ([elementName isEqualToString:@"memberid"])
{
tmemberid = [[NSMutableString alloc] init];
}

if ([elementName isEqualToString:@"count"])
{
tcount = [[NSMutableString alloc] init];
}
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ([currentElement isEqualToString:@"shared"])
{
[tshared appendString:string];
}

if ([currentElement isEqualToString:@"fullname"])
{
[tfullname appendString:string];
}

if ([currentElement isEqualToString:@"nationality"])
{
[tnationality appendString:string];
}

if ([currentElement isEqualToString:@"subject"])
{
[tsubject appendString:string];
}

if ([currentElement isEqualToString:@"accommodation"])
{
[taccommodation appendString:string];
}

if ([currentElement isEqualToString:@"memberid"])
{
[tmemberid appendString:string];
}

if ([currentElement isEqualToString:@"count"])
{
[tcount appendString:string];
}
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:@"shared"])
{
[lshared addObject:tshared];

[tshared release];

}

if ([elementName isEqualToString:@"fullname"])
{
[lfullname addObject:tfullname];

[tfullname release];
}

if ([elementName isEqualToString:@"nationality"])
{
[tnationality appendString:@".png"];

[lnationality addObject:tnationality];

[tnationality release];
}

if ([elementName isEqualToString:@"subject"])
{
[lsubject addObject:tsubject];

[tsubject release];
}

if ([elementName isEqualToString:@"accommodation"])
{
[laccommodation addObject:taccommodation];

[taccommodation release];
}

if ([elementName isEqualToString:@"memberid"])
{
[lmemberid addObject:tmemberid];

[tmemberid release];
}

if ([elementName isEqualToString:@"count"])
{
count = [[NSMutableString alloc] init];

count = tcount;

[tcount release];
}
}

-(void)fetchsuggestions
{
MyManager *sharedManager = [MyManager sharedManager];

suggestiondetailxml = [[NSMutableData alloc] init];

NSString *urlString = [NSString stringWithFormat:@"http://secreturl.com/a.php?username=%@&password=%@",sharedManager.user,sharedManager.passw];

NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *req = [NSURLRequest requestWithURL:url];

connection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES];
}

-(void) connection:(NSURLConnection *)conn didReceiveData:(NSData *)data
{
[suggestiondetailxml appendData:data];
}

-(void) connectionDidFinishLoading:(NSURLConnection *)conn
{
NSString *xmlcheck = [[[NSString alloc] initWithData:suggestiondetailxml encoding:NSUTF8StringEncoding] autorelease];

NSLog(@"%@",xmlcheck);

lshared = [[NSMutableArray alloc] init];
lfullname = [[NSMutableArray alloc] init];
lnationality = [[NSMutableArray alloc] init];
lsubject = [[NSMutableArray alloc] init];
laccommodation = [[NSMutableArray alloc] init];
lmemberid = [[NSMutableArray alloc] init];

NSXMLParser *parser = [[NSXMLParser alloc] initWithData: suggestiondetailxml];
[parser setDelegate:self];
[parser parse];
[parser release];

//[xmlcheck release]; //causes crash

[connection release];
connection = nil;

[suggestiondetailxml release];

[[self tableView] reloadData];
NSLog(@"%@",lmemberid);
}

- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}

- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
[super viewDidLoad];
[[self navigationItem] setTitle:@"My Culture"];

// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;

// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self fetchsuggestions];
}

- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[lshared release];
[lfullname release];
[lnationality release];
[lsubject release];
[laccommodation release];
[lmemberid release];
//[count release];
}

- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}

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


-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 93.0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
if (cell==nil)
{
[[NSBundle mainBundle] loadNibNamed:@"SuggestedFriendCell" owner:self options:nil];
cell = maincell;
//self.detailcell = nil;
}
UILabel *name;
name = (UILabel *)[cell viewWithTag:4];
name.text=[lfullname objectAtIndex:indexPath.row];

if(([[lshared objectAtIndex:indexPath.row]isEqualToString:@"all"])||([[lshared objectAtIndex:indexPath.row]isEqualToString:@"nationalityandaccommodation"])||([[lshared objectAtIndex:indexPath.row]isEqualToString:@"nationalityandsubject"])||([[lshared objectAtIndex:indexPath.row]isEqualToString:@"nationality"]))
{
UIImageView *nationality;
nationality = (UIImageView *)[cell viewWithTag:1];

nationality.image=[UIImage imageNamed:[lnationality objectAtIndex:indexPath.row]];
}

if(([[lshared objectAtIndex:indexPath.row]isEqualToString:@"all"])||([[lshared objectAtIndex:indexPath.row]isEqualToString:@"nationalityandaccommodation"])||([[lshared objectAtIndex:indexPath.row]isEqualToString:@"subjectandaccommodation"])||([[lshared objectAtIndex:indexPath.row]isEqualToString:@"accommodation"]))
{
UIImageView *accommodation;
accommodation = (UIImageView *)[cell viewWithTag:2];
accommodation.image=[UIImage imageNamed:@"accommodation.jpeg"];
}

if(([[lshared objectAtIndex:indexPath.row]isEqualToString:@"all"])||([[lshared objectAtIndex:indexPath.row]isEqualToString:@"nationalityandsubject"])||([[lshared objectAtIndex:indexPath.row]isEqualToString:@"subjectandaccommodation"])||([[lshared objectAtIndex:indexPath.row]isEqualToString:@"subject"]))
{
UIImageView *subject;
subject = (UIImageView *)[cell viewWithTag:3];
subject.image=[UIImage imageNamed:@"degree.jpg"];
}
return cell;
}

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/

MyManager *sharedManager = [MyManager sharedManager];

int row = indexPath.row;

sharedManager.interrogatedmemberid=[lmemberid objectAtIndex:row];

ViewFriendProfile *frienddetail_vc = [[[ViewFriendProfile alloc] init] autorelease];

[[self navigationController] pushViewController:frienddetail_vc animated:YES];


}

-(void)dealloc
{





[super dealloc];

}

@end

当我取消注释 [tcount release] 时,它会导致崩溃:为什么会这样。

PS:我对格式很抱歉:如何复制和粘贴代码以使其出现在代码块中?

谢谢

最佳答案

要了解发生了什么,您需要了解 viewWillAppear 和 viewWillDisappear 是如何工作的。

这两种方法在 View Controller 的生命周期中被多次调用,具体取决于您是在推送/弹出 View Controller ,还是从 View Controller 显示/关闭模式。

例如:

  • 推送 viewController A:在 viewController A 上调用 viewDidLoad 和 viewWillAppear
  • 从 viewController A 推送 viewController B:在 viewController A 上调用 viewWillDisappear,在 viewController B 上调用 viewDidLoad 和 viewWillAppear
  • 弹出 viewController B 回到 viewController A:viewWillDisappear 在 vi​​ewController B 上调用,viewDidUnload 在 vi​​ewController B 上调用,dealloc 在 vi​​ewController B 上调用,viewWillAppear 在 vi​​ewController A 上调用
  • 从 viewController A 显示模式: viewWillDisappear 在 vi​​ewController A 上调用
  • 关闭模态:viewWillAppear 在 vi​​ewController A 上调用
  • 弹出 viewController A:viewWillDisappear 在 vi​​ewController A 上调用,viewDidUnload 在 vi​​ewController A 上调用,dealloc 在 vi​​ewController A 上调用

  • 听起来您在 viewWillAppear 中分配一个对象,该对象被多次调用,但在仅调用一次的 dealloc 方法中释放它,因此内存泄漏 .

    在 viewWillDisappear 中释放您的对象是平衡 viewWillAppear 中的分配,因此没有泄漏。

    在这一点上我只能说,除非您有充分的理由在 viewWillAppear 中分配某些东西(即,您知道自己在做什么),否则不要这样做。

    我不能告诉你更多......为你正在尝试做的事情发布更多代码可能会帮助你获得更详细的答案:)

    希望这有所帮助。

    编辑 代码发布后。

    首先,你的意思是'当我取消注释 [ 计数 释放]'?您可以发布该崩溃的控制台消息吗?它崩溃了,因为 parserDidEndElement 是它被分配的地方,但它正在 viewWillDisappear 中被释放。如果这些不平衡,您将获得 EXC_BAD_ACCESS

    来到你的内存状态。我现在明白为什么在 viewWillDisappear 中发布可以修复泄漏。您调用 fetchsuggestions在 viewWillAppear 上,它反过来创建并触发 URL 请求。这将导致 connectionDidFinishLoading在成功连接时被调用。这是您分配各种 ivars 的地方。由于我之前提到 viewWillAppear 被多次调用,这意味着您要多次触发连接,这会导致 connectionDidFinishLoading被多次调用。

    这就是为什么在 viewWillDisappear 中发布的原因修复泄漏,因为对于 viewWillAppear 上的每个分配, 你通过释放 viewWillDisappear 来平衡它.

    你错过了什么是你的程序会在没有可用网络时崩溃。这是因为 connectionDidFinishLoading没有网络时不会被调用。现在,当您尝试在 viewWillDisappear 中发布时,当您尝试释放以前在 viewWillAppear 中从未再次分配的实例时,您将获得 EXC_BAD_ACCESS .

    我认为我不需要调用 fetchsuggestions在 viewWillAppear 上多次,除非您是故意这样做的。

    这是我现在看到的最明显的事情......问题可能是(并且可能是)多个,但是我们如何从重构代码开始,记住 viewWillAppear/Disappear 中的多个不平衡分配和释放可能不是一个好主意...? :)

    关于iphone - 用于内存管理的 dealloc 与 ViewDidDissapear,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7974557/

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