返回时出现问题,两个标签之间出现第四个错误,显示EXC_BAD_ACCESS错误。可以查看两个视图。假设我有两个视图A和B.如果我去B,我能够毫无问题地看到视图,然后移动到A,这很好。但是当返回B时会发生错误。我相信这是一些内存泄漏但无法找到它。
A - 控制器
@implementation FriendsViewController
@synthesize tableViewIB;
@synthesize userArray;
@synthesize xmlData;
@synthesize navigationController;
@synthesize localUser;
@synthesize interestingTags;
-(void)startParsingOnlineUsers;
{
NSXMLParser *idParser = [[NSXMLParser alloc] initWithData:xmlData];
idParser.delegate = self;
[idParser parse];
[idParser release];
}
-(void)parserDidStartDocument:(NSXMLParser *)parser
{
currentElementName = nil;
currentText = nil;
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:@"friend"])
{
[currentUserDict release];
currentUserDict = [[NSMutableDictionary alloc] initWithCapacity:[interestingTags count]];
}
else if([interestingTags containsObject:elementName])
{
currentElementName = elementName;
currentText = [[NSMutableString alloc] init];
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
[currentText appendString:string];
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:currentElementName])
{
[currentUserDict setValue: currentText forKey: currentElementName];
}
else if([elementName isEqualToString:@"friend"])
{
[self.userArray addObject:currentUserDict];
}
NSLog(@"ending");
[currentText release];
currentText = nil;
}
-(void)parserDidEndDocument:(NSXMLParser *)parser
{
[tableViewIB reloadData];
}
//**********************TABLE CODE***************************************
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.userArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *Cell = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Cell];
if(cell ==nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:Cell] autorelease];
}
NSUInteger row = [indexPath row];
NSDictionary *rowData = [self.userArray objectAtIndex:row];
NSMutableString *textName = [[NSString alloc] initWithFormat:@"User: %@", [rowData objectForKey:@"username"]];
NSMutableString *gender = [[NSString alloc] initWithFormat:@"%@", [rowData objectForKey:@"gender"]];
cell.textLabel.text = textName;
cell.detailTextLabel.text = gender;
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSUInteger row = [indexPath row];
NSDictionary *rowData = [self.userArray objectAtIndex:row];
NSMutableString *textNumber = [[NSString alloc] initWithFormat:@"%@", [rowData objectForKey:@"number"]];
NSString *phoneNumber = textNumber;
NSString *phoneNumberScheme = [NSString stringWithFormat:@"http://%@", phoneNumber];
//NSlog(phoneNumberScheme);
phoneNumberScheme = [phoneNumberScheme stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneNumberScheme]];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
-(void)viewWillAppear:(BOOL)animated
{
self.userArray = [[NSMutableArray alloc] init];
interestingTags = [[NSSet alloc] initWithObjects: INTERESTING_TAG_NAMES];
[self.userArray removeAllObjects];
NSMutableData *data = [NSMutableData data];
NSString *filePath = [self dataFilePath];
if([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
NSString *string = [[NSString alloc] initWithContentsOfFile:filePath];
self.localUser = string;
[string release];
}
NSString *localString = [[NSString alloc] initWithFormat:@"userid=%@", self.localUser]; //build URL String
[data appendData:[localString dataUsingEncoding:NSUTF8StringEncoding]]; //build URL String
NSURL *url = [NSURL URLWithString:@"http://www.url.com/friends.php"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //request with the chosen url
[request setHTTPMethod:@"POST"]; //http method
[request setHTTPBody:data]; //set data of request to built URL String
NSURLResponse *response;
NSError *err;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err]; //start the request and store data in responseData
NSLog(@"responseData: %@", responseData);
xmlData = responseData; //store responseData in global variable
[self startParsingOnlineUsers];
[tableViewIB reloadData];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[self.navigationController release];
[self.tableViewIB release];
[self.userArray release];
[self.xmlData release];
[self.localUser release];
[self.interestingTags release];
[super dealloc];
}
- (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
{
self.title = @"Friends";
navigationController.navigationBar.tintColor = [[UIColor alloc] initWithRed:154.0 / 255 green:188.0 / 255 blue:52.0 / 255 alpha:1.0];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
self.userArray = nil;
self.xmlData = nil;
self.localUser = nil;
self.navigationController = nil;
self.tableViewIB = nil;
self.interestingTags = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(NSString *)dataFilePath
{
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [path objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:kFilename];
}
@end
B - 控制器
@implementation FriendRequestsViewController
@synthesize navigationController;
@synthesize tableViewIB;
@synthesize userArray;
@synthesize xmlData;
@synthesize remoteUser;
@synthesize localUser;
-(void)removeArrayObjects
{
[self.userArray removeAllObjects];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.userArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *Cell = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Cell];
if(cell ==nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:Cell] autorelease];
}
NSUInteger row = [indexPath row];
NSDictionary *rowData = [self.userArray objectAtIndex:row];
NSMutableString *textName = [[NSString alloc] initWithFormat:@"User: %@", [rowData objectForKey:@"username"]];
NSMutableString *gender = [[NSString alloc] initWithFormat:@"%@", [rowData objectForKey:@"gender"]];
cell.textLabel.text = textName;
cell.detailTextLabel.text = gender;
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSUInteger row = [indexPath row];
NSDictionary *rowData = [self.userArray objectAtIndex:row];
NSMutableString *remoteUserId = [[NSString alloc] initWithFormat:@"%@", [rowData objectForKey:@"id"]]; //get the user ID of friend request
self.remoteUser = remoteUserId;
NSMutableString *messageText = [[NSString alloc] initWithFormat:@"Do You Want To Accept %@'s Friend Request", [rowData objectForKey:@"username"]];
UIActionSheet *reportUser = [[UIActionSheet alloc] initWithTitle:messageText delegate:self cancelButtonTitle:@"No" destructiveButtonTitle:@"Yes" otherButtonTitles:nil];
[reportUser showInView:self.parentViewController.tabBarController.view];
[reportUser release];
/*NSMutableString *textNumber = [[NSString alloc] initWithFormat:@"%@", [rowData objectForKey:@"number"]];
NSString *phoneNumber = textNumber;
NSString *phoneNumberScheme = [NSString stringWithFormat:@"http://%@", phoneNumber];
//NSlog(phoneNumberScheme);
phoneNumberScheme = [phoneNumberScheme stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneNumberScheme]];*/
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
-(void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if(buttonIndex != [actionSheet cancelButtonIndex])
{
NSLog(@"Accept Friend Request");
[self performSelectorInBackground:@selector(AcceptFriendRequest) withObject:nil];
}
}
-(void)AcceptFriendRequest
{
}
-(void)viewWillAppear:(BOOL)animated
{
self.userArray = [[NSMutableArray alloc] init];
interestingTags = [[NSSet alloc] initWithObjects: INTERESTING_TAG_NAMES];
[xmlData release];
xmlData = [[NSMutableData alloc] init]; //alloc the holder for xml, may be large so we use nsmutabledata type
NSMutableData *data = [NSMutableData data];
NSString *filePath = [self dataFilePath];
if([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
NSString *string = [[NSString alloc] initWithContentsOfFile:filePath];
self.localUser = string;
[string release];
}
NSString *useridString = [[NSString alloc] initWithFormat:@"userid=%@", self.localUser]; //build URL String
[data appendData:[useridString dataUsingEncoding:NSUTF8StringEncoding]]; //build URL String
NSURL *url = [NSURL URLWithString:@"http://www.url.com/friendrequests.php"];//url string to download
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //request with the chosen url
[request setHTTPMethod:@"POST"]; //http method
[request setHTTPBody:data]; //set data of request to built URL String
NSURLResponse *response;
NSError *err;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err]; //start the request and store data in responseData
NSLog(@"responseData: %@", responseData);
xmlData = responseData; //store responseData in global variable
[self startParsingFriendRequests];
[super viewWillAppear:animated];
}
//***********************START PARSING***********************************
-(void)startParsingFriendRequests
{
[self.userArray removeAllObjects];
//NSLog(@"parsing init");
NSXMLParser *onlineUserParser = [[NSXMLParser alloc] initWithData:xmlData]; //uses the NSMutableData data type to parse
onlineUserParser.delegate = self; //set the delegate to this viewControlelr
[onlineUserParser parse];
[onlineUserParser release];
}
//called when the document is parsed
-(void)parserDidStartDocument:(NSXMLParser *)parser
{
//NSLog(@"parsing started");
currentElementName = nil;
currentText = nil;
}
//this is called for each xml element
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
//NSLog(@"started element");
if ([elementName isEqualToString:@"friend"]) //if elementName == status then start of new tweet so make new dictionary
{
[currentUserDict release];
currentUserDict = [[NSMutableDictionary alloc] initWithCapacity:[interestingTags count]]; //make dictionary with two sections
}
else if([interestingTags containsObject:elementName]) //if current element is one stored in interesting tag, hold onto the elementName and make a new string to hold its value
{
currentElementName = elementName; //hold onto current element name
currentText = [[NSMutableString alloc] init];
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
//NSLog(@"appending");
[currentText appendString:string];
}
//after each element it goes back to the parent after calling this method
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:currentElementName])
{
[currentUserDict setValue: currentText forKey: currentElementName];
}
else if([elementName isEqualToString:@"friend"])
{
[self.userArray addObject:currentUserDict];
//eventually placed in table just testing for now
}
[currentText release];
currentText = nil;
}
-(void)parserDidEndDocument:(NSXMLParser *)parser
{
[tableViewIB reloadData];
//NSLog(@"DONE PARSING DOCUMENT");
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[userArray release];
[xmlData release];
[remoteUser release];
[localUser release];
[navigationController release];
[tableViewIB release];
[super dealloc];
}
- (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
{
self.title = @"Friend Requests";
navigationController.navigationBar.tintColor = [[UIColor alloc] initWithRed:154.0 / 255 green:188.0 / 255 blue:52.0 / 255 alpha:1.0];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
self.userArray = nil;
self.xmlData = nil;
self.remoteUser = nil;
self.localUser = nil;
self.navigationController = nil;
self.tableViewIB = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(NSString *)dataFilePath
{
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [path objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:kFilename];
}
2011-08-26 13:07:12.972 FaceConnect [2375:207] *终止app到期 未捕获的异常'NSInvalidArgumentException',原因: ' - [NSConcreteData countByEnumeratingWithState:objects:count:]: 无法识别的选择器发送到实例0x6001710' * 在第一次投掷时调用堆栈:(0 CoreFoundation
0x00dd55a9 exceptionPreprocess + 185 1 libobjc.A.dylib
0x00f29313 objc_exception_throw + 44 2 CoreFoundation
0x00dd70bb - [NSObject(NSObject)doesNotRecognizeSelector:] + 187 3
CoreFoundation 0x00d46966 __ 转发 + 966 4 CoreFoundation 0x00d46522 _CF_forwarding_prep_0 + 50 5 UIKit
0x000613fb - [UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:] + 174 6 UIKit 0x0005848a - [UIView(内部)_addSubview:定位:relativeTo:] + 370 7
UIKit 0x00056aa3 - [UIView(Hierarchy) addSubview:] + 57 8 UIKit 0x000b5a24 - [UITransitionView过渡:fromView:toView:] + 563 9 UIKit
0x000b4dcd - [UITransitionView转换:toView:] + 129 10 UIKit
0x000ea0a7 - [UITabBarController transitionFromViewController:toViewController:过渡:shouldSetSelected:] + 459 11 UIKit 0x000e8aaa - [UITabBarController transitionFromViewController:toViewController:] + 64 12 UIKit 0x000ea8a2 - [UITabBarController _setSelectedViewController:] + 263 13 UIKit
0x000ea711 - [UITabBarController _tabBarItemClicked:] + 352 14 UIKit 0x000274fd - [UIApplication sendAction:to:from:forEvent:] + 119 15 UIKit 0x00229ce6 - [UITabBar _sendAction:withEvent:] + 422 16 UIKit
0x000274fd - [UIApplication sendAction:to:from:forEvent:] + 119 17 UIKit 0x000b7799 - [UIControl sendAction:to:forEvent:] + 67 18 UIKit
0x000b9c2b - [UIControl(内部)_sendActionsForEvents:withEvent:] + 527 19 UIKit 0x000b7750 - [UIControl sendActionsForControlEvents:] + 49 20 UIKit
0x000274fd - [UIApplication sendAction:to:from:forEvent:] + 119 21 UIKit 0x000b7799 - [UIControl sendAction:to:forEvent:] + 67 22 UIKit
0x000b9c2b - [UIControl(内部)_sendActionsForEvents:withEvent:] + 527 23 UIKit 0x000b87d8 - [UIControl touchesEnded:withEvent:] + 458 24 UIKit
0x0004bded - [UIWindow _sendTouchesForEvent:] + 567 25 UIKit
0x0002cc37 - [UIApplication sendEvent:] + 447 26 UIKit
0x00031f2e _UIApplicationHandleEvent + 7576 27 GraphicsServices
0x0100e992 PurpleEventCallback + 1550 28 CoreFoundation
0x00db6944 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION + 52 29 CoreFoundation 0x00d16cf7 __CFRunLoopDoSource1 + 215 30 CoreFoundation
0x00d13f83 __CFRunLoopRun + 979 31 CoreFoundation
0x00d13840 CFRunLoopRunSpecific + 208 32 CoreFoundation
0x00d13761 CFRunLoopRunInMode + 97 33图形服务
0x0100d1c4 GSEventRunModal + 217 34图形服务
0x0100d289 GSEventRun + 115 35 UIKit
0x00035c93 UIApplicationMain + 1160 36 FaceConnect
0x00002509 main + 121 37 FaceConnect
0x00002485 start + 53)在抛出一个实例后终止调用 'NSException'当前语言:auto;目前objective-c(gdb)
答案 0 :(得分:1)
在您的 - (void)viewWillAppear:(BOOL)动画调用中,您正在调用同步URL请求,这通常是一种不好的做法,因为viewWillAppear是UI管理系统的一部分。同步请求是一个阻塞调用,将“冻结”UI,并可能导致某些事情被延迟。
我在调试日志中看到了EXC_BAD_ACCESS,但这通常与发布后访问的对象有关。
要看的另一个区域是你的NSXMLParser,看起来你过早地发布了它。在这种情况下,解析器正在运行,然后它被释放,因此无法保证委托可能存在。
-(void)startParsingOnlineUsers;
{
NSXMLParser *idParser = [[NSXMLParser alloc] initWithData:xmlData];
idParser.delegate = self;
[idParser parse];
[idParser release];
}
如果你看一下NSXML Parser的类定义,它就说没有保留委托。
// delegate management. The delegate is not retained.
- (id <NSXMLParserDelegate>)delegate;
希望有所帮助
答案 1 :(得分:0)
我认为你发布了一些无法发布的对象 第二种观点。
- (void)dealloc
{
[super dealloc];
}
然后检查。
答案 2 :(得分:0)
我现在不在我的Mac上,所以我无法验证我的假设/想法。
我认为这与以下一行有关
xmlData = responseData; //store responseData in global variable
在这里,您将xmlData指向responseData,而不是将对象内容复制到xmlData中。
如果responseData被自动释放,xmlData将指向不存在的内容。因此,下次出现视图时,以下行将导致崩溃
[xmlData release];
如果我的假设是正确的,您应该使用以下代码
xmlData = [responseData mutableCopy]; //store responseData in global variable