RNs*_*ost 1 iphone memory-management objective-c nsxmlparser ios
我有几个视图解析从互联网上下载的xml.
仪器泄漏工具告诉我,当我在dealloc方法中释放数据成员时我有泄漏但不是当我放入[objectname release];内部时viewDidDissapear.
这是一个主要的罪吗?
来自ac/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
Run Code Online (Sandbox Code Playgroud)
当我取消注释[tcount release]时,它会导致崩溃:为什么会这样.
PS:我很抱歉格式化:如何复制和粘贴代码,使其出现在代码块中?
谢谢
要了解正在发生的事情,您需要了解viewWillAppear和viewWillDis似乎如何工作.
在视图控制器的生命周期中,这两种方法都会被多次调用,具体取决于您是按下/弹出一个视图控制器,还是从视图控制器中显示/取消一个模态.
例如:
听起来像是在viewWillAppear中分配一个对象,它被多次调用,但是在dealloc方法中释放它,只调用一次,因此内存泄漏.
在viewWillDisappear中释放对象是在viewWillAppear中平衡分配,因此没有泄漏.
我现在只能说,除非你有充分的理由在viewWillAppear中分配一些东西(也就是说,你知道你在做什么),不要这样做.
我可以告诉你更多的内容...为你想要做的事情发布更多代码可能会帮助你得到更详细的答案:)
希望这会有所帮助.
代码发布后编辑.
首先,你的意思是"当我取消注释[ 计数释放]"时?你可以发布该崩溃的控制台消息吗?它崩溃了,因为parserDidEndElement是它分配的地方,但是它已经在viewWillDisappear中发布了.如果这些没有平衡,您将获得EXC_BAD_ACCESS
来你的记忆情况.我现在看到为什么在viewWillDisappear中释放修复了泄漏.您正在调用fetchsuggestionsviewWillAppear,而viewWillAppear又会创建并触发URL请求.这将导致connectionDidFinishLoading成功连接被调用.这是您分配各种ivars的地方.由于我之前提到过viewWillAppear被多次调用,这意味着你多次触发连接会导致connectionDidFinishLoading被多次调用.
这就是为什么释放viewWillDisappear修复泄漏的原因,因为对于a上的每个分配viewWillAppear,你通过释放来平衡它viewWillDisappear.
你错过的是你的程序会在没有可用的网络时崩溃.这是因为connectionDidFinishLoading当没有网络时不会被调用.现在,当您尝试发布时viewWillDisappear,您将获得一个EXC_BAD_ACCESS,因为您尝试释放之前从未分配过的已释放的实例viewWillAppear.
我不认为我需要fetchsuggestions在viewWillAppear上多次调用,除非你是故意这样做的.
这是我现在看到的最明显的事情......问题可能(并且可能是)多重,但我们如何从重构代码开始,记住viewWillAppear/Disappear中的多个不平衡的alloc和release可能不是一个好主意...?:)
| 归档时间: |
|
| 查看次数: |
338 次 |
| 最近记录: |