使用标签栏在视图之间切换时 iPhone 应用程序崩溃
我有一个 iPhone 应用程序,当我在两个选项卡之间切换 4 或 5 次时,该应用程序会崩溃。其中一个视图有一个 UITableView,可以在您键入时进行搜索,我有一种感觉,这就是出了问题的地方。在界面生成器中,如果我将引用插座的表视图连接到包含搜索结果的数组,则您键入的搜索效果很好,但随后我遇到了视图之间的切换问题。 如果我不建立此连接,搜索将无法正常进行。当我搜索后上下滚动时,它只会刷新表格视图。
有谁知道可能出了什么问题吗?我已经为此苦苦挣扎了好几天,而且我对 iPhone 编程还很陌生。谢谢
编辑: 我在控制台中收到此错误:
2011-07-30 10:52:09.835 ConnectIPhone[7019:207] -[NSCFString setReorderedIndexPath:]: unrecognized selector sent to instance 0x4e48370
2011-07-30 10:52:09.838 ConnectIPhone[7019:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString setReorderedIndexPath:]: unrecognized selector sent to instance 0x4e48370'
*** Call stack at first throw:
(
0 CoreFoundation 0x00dd6be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x00f2b5c2 objc_exception_throw + 47
2 CoreFoundation 0x00dd86fb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x00d48366 ___forwarding___ + 966
4 CoreFoundation 0x00d47f22 _CF_forwarding_prep_0 + 50
5 UIKit 0x00359171 -[UITableView reloadData] + 446
6 ConnectIPhone 0x0000649e -[PeopleViewController viewWillAppear:] + 460
7 UIKit 0x003a02bf -[UITabBarController transitionFromViewController:toViewController:transition:shouldSetSelected:] + 263
8 UIKit 0x0039ed86 -[UITabBarController transitionFromViewController:toViewController:] + 64
9 UIKit 0x003a0b7e -[UITabBarController _setSelectedViewController:] + 263
10 UIKit 0x003a09ed -[UITabBarController _tabBarItemClicked:] + 352
11 UIKit 0x002dfa6e -[UIApplication sendAction:to:from:forEvent:] + 119
12 UIKit 0x004dd1f2 -[UITabBar _sendAction:withEvent:] + 422
13 UIKit 0x002dfa6e -[UIApplication sendAction:to:from:forEvent:] + 119
14 UIKit 0x0036e1b5 -[UIControl sendAction:to:forEvent:] + 67
15 UIKit 0x00370647 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
16 UIKit 0x0036e16c -[UIControl sendActionsForControlEvents:] + 49
17 UIKit 0x002dfa6e -[UIApplication sendAction:to:from:forEvent:] + 119
18 UIKit 0x0036e1b5 -[UIControl sendAction:to:forEvent:] + 67
19 UIKit 0x00370647 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
20 UIKit 0x0036f1f4 -[UIControl touchesEnded:withEvent:] + 458
21 UIKit 0x003040d1 -[UIWindow _sendTouchesForEvent:] + 567
22 UIKit 0x002e537a -[UIApplication sendEvent:] + 447
23 UIKit 0x002ea732 _UIApplicationHandleEvent + 7576
24 GraphicsServices 0x0170ca36 PurpleEventCallback + 1550
25 CoreFoundation 0x00db8064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
26 CoreFoundation 0x00d186f7 __CFRunLoopDoSource1 + 215
27 CoreFoundation 0x00d15983 __CFRunLoopRun + 979
28 CoreFoundation 0x00d15240 CFRunLoopRunSpecific + 208
29 CoreFoundation 0x00d15161 CFRunLoopRunInMode + 97
30 GraphicsServices 0x0170b268 GSEventRunModal + 217
31 GraphicsServices 0x0170b32d GSEventRun + 115
32 UIKit 0x002ee42e UIApplicationMain + 1160
33 ConnectIPhone 0x00001ca0 main + 102
34 ConnectIPhone 0x00001c31 start + 53
35 ??? 0x00000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'
cellForRowAtIndexPath 代码:
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath: (NSIndexPath*)indexPath
{
static NSString *cellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil){
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
}
row = [indexPath row];
if (row >= [listData count]){
cell.textLabel.text = @"";
}else {
NSMutableString *cellText = [[NSMutableString alloc] initWithString:[[listData objectAtIndex:row] objectAtIndex:0]];
[cellText appendString:@", "];
[cellText appendString:[[listData objectAtIndex:row] objectAtIndex:1]];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.text = cellText;
[cellText release];
}
return cell;
}
类:
#import "PeopleViewController.h"
@implementation PeopleViewController
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization.
}
return self;
}
*/
-(void)loadView
{
[super loadView];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
self.editing = YES;
cHandle = [ConnectHandler new];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
userID = [defaults objectForKey:kUserID];
password = [defaults objectForKey:kPassword];
NSString *response = [cHandle doSearch:@"" :userID :[cHandle hashPass:password]];
listData = (NSMutableArray*)[cHandle parseSearch:response];
self.view.autoresizesSubviews = YES;
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[listTable reloadData];
[super viewDidLoad];
}
-(void)viewWillAppear:(BOOL)animated
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
userID = [defaults objectForKey:kUserID];
password = [defaults objectForKey:kPassword];
//initiate the connection handler, get the json response
cHandle = [ConnectHandler new];
NSString *response = [cHandle doSearch:@"": userID :[cHandle hashPass:password]];
listData = (NSMutableArray*)[cHandle parseSearch:response];
//[listTable reloadData];
[response release];
[super viewWillAppear:animated];
}
-(void)viewWillDisappear:(BOOL)animated{
[listData release];
[listTable release];
[super viewWillDisappear:animated];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return YES;
}
- (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.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
#pragma mark -
#pragma mark Search View
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
listData = nil;
[listTable reloadData];
query = searchBar.text;
[searchBar resignFirstResponder];
[listData removeAllObjects];
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
searchBar.text = @"";
[listTable reloadData];
[searchBar resignFirstResponder];
query = searchBar.text;
[listData removeAllObjects];
[self loadSearch:query];
}
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)searchText {
listData = nil;
[listTable reloadData];
query = searchBar.text;
[listData removeAllObjects];
[self loadSearch:query];
}
-(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
[listTable reloadData];
}
-(void)loadSearch:(NSString *)q{
self.editing = YES;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
userID = [defaults objectForKey:kUserID];
password = [defaults objectForKey:kPassword];
NSString *response = [cHandle doSearch:q :userID :[cHandle hashPass:password]];
listData = (NSMutableArray*)[cHandle parseSearch:response];
[listTable reloadData];
for (UITableViewCell *cell in [listTable visibleCells]) {
NSIndexPath *cellIndexPath = [listTable indexPathForCell:cell];
[listTable cellForRowAtIndexPath:cellIndexPath];
}
[response release];
}
- (void)dealloc {
[listData release];
[cHandle release];
[super dealloc];
}
#pragma mark -
#pragma mark Table View Data Source Methods
-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section{
return [listData count];
}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
static NSString *cellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil){
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
}
row = [indexPath row];
if (row >= [listData count]){
cell.textLabel.text = @"";
}else {
NSMutableString *cellText = [[NSMutableString alloc] initWithString:[[listData objectAtIndex:row] objectAtIndex:0]];
[cellText appendString:@", "];
[cellText appendString:[[listData objectAtIndex:row] objectAtIndex:1]];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.text = cellText;
[cellText release];
}
return cell;
}
-(UITableViewCellEditingStyle)tableView:(UITableView*)tableView editingStyleForRowAtIndexPath:(NSIndexPath*)indexPath
{
if (self.editing && indexPath.row == ([listData count]))
return UITableViewCellEditingStyleInsert;
else {
return UITableViewCellEditingStyleDelete;
}
}
-(void)tableView:(UITableView*)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath*)indexPath {
[listTable beginUpdates];
if (editingStyle == UITableViewCellEditingStyleDelete)
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setUserInteractionEnabled:NO];
cell.selected = NO;
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else {
}
[listTable endUpdates];
}
-(BOOL)tableView:(UITableView*)tableView canMoveRowAtIndexPath:(NSIndexPath*)indexPath
{
return YES;
}
@end
I have an iphone application that crashes when I switch between two of the tabs 4 or 5 times. One of the views has a UITableView that searches as you type and I have a feeling that's where something is going wrong. In the Interface Builder if I connect the Table Views referencing outlet to the array that contains the search results the search as you type works perfectly but then I have the switching between views problem.
If I do not make this connection the search does not work right. It only refreshes the table view when I scroll up and down after searching.
Does anyone have any idea what could be going wrong? I've been struggling with this for days and I'm very new to iphone programming. Thank you
EDIT:
I'm getting this error in the console:
2011-07-30 10:52:09.835 ConnectIPhone[7019:207] -[NSCFString setReorderedIndexPath:]: unrecognized selector sent to instance 0x4e48370
2011-07-30 10:52:09.838 ConnectIPhone[7019:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString setReorderedIndexPath:]: unrecognized selector sent to instance 0x4e48370'
*** Call stack at first throw:
(
0 CoreFoundation 0x00dd6be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x00f2b5c2 objc_exception_throw + 47
2 CoreFoundation 0x00dd86fb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x00d48366 ___forwarding___ + 966
4 CoreFoundation 0x00d47f22 _CF_forwarding_prep_0 + 50
5 UIKit 0x00359171 -[UITableView reloadData] + 446
6 ConnectIPhone 0x0000649e -[PeopleViewController viewWillAppear:] + 460
7 UIKit 0x003a02bf -[UITabBarController transitionFromViewController:toViewController:transition:shouldSetSelected:] + 263
8 UIKit 0x0039ed86 -[UITabBarController transitionFromViewController:toViewController:] + 64
9 UIKit 0x003a0b7e -[UITabBarController _setSelectedViewController:] + 263
10 UIKit 0x003a09ed -[UITabBarController _tabBarItemClicked:] + 352
11 UIKit 0x002dfa6e -[UIApplication sendAction:to:from:forEvent:] + 119
12 UIKit 0x004dd1f2 -[UITabBar _sendAction:withEvent:] + 422
13 UIKit 0x002dfa6e -[UIApplication sendAction:to:from:forEvent:] + 119
14 UIKit 0x0036e1b5 -[UIControl sendAction:to:forEvent:] + 67
15 UIKit 0x00370647 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
16 UIKit 0x0036e16c -[UIControl sendActionsForControlEvents:] + 49
17 UIKit 0x002dfa6e -[UIApplication sendAction:to:from:forEvent:] + 119
18 UIKit 0x0036e1b5 -[UIControl sendAction:to:forEvent:] + 67
19 UIKit 0x00370647 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
20 UIKit 0x0036f1f4 -[UIControl touchesEnded:withEvent:] + 458
21 UIKit 0x003040d1 -[UIWindow _sendTouchesForEvent:] + 567
22 UIKit 0x002e537a -[UIApplication sendEvent:] + 447
23 UIKit 0x002ea732 _UIApplicationHandleEvent + 7576
24 GraphicsServices 0x0170ca36 PurpleEventCallback + 1550
25 CoreFoundation 0x00db8064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
26 CoreFoundation 0x00d186f7 __CFRunLoopDoSource1 + 215
27 CoreFoundation 0x00d15983 __CFRunLoopRun + 979
28 CoreFoundation 0x00d15240 CFRunLoopRunSpecific + 208
29 CoreFoundation 0x00d15161 CFRunLoopRunInMode + 97
30 GraphicsServices 0x0170b268 GSEventRunModal + 217
31 GraphicsServices 0x0170b32d GSEventRun + 115
32 UIKit 0x002ee42e UIApplicationMain + 1160
33 ConnectIPhone 0x00001ca0 main + 102
34 ConnectIPhone 0x00001c31 start + 53
35 ??? 0x00000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'
cellForRowAtIndexPath code:
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath: (NSIndexPath*)indexPath
{
static NSString *cellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil){
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
}
row = [indexPath row];
if (row >= [listData count]){
cell.textLabel.text = @"";
}else {
NSMutableString *cellText = [[NSMutableString alloc] initWithString:[[listData objectAtIndex:row] objectAtIndex:0]];
[cellText appendString:@", "];
[cellText appendString:[[listData objectAtIndex:row] objectAtIndex:1]];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.text = cellText;
[cellText release];
}
return cell;
}
The class:
#import "PeopleViewController.h"
@implementation PeopleViewController
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization.
}
return self;
}
*/
-(void)loadView
{
[super loadView];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
self.editing = YES;
cHandle = [ConnectHandler new];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
userID = [defaults objectForKey:kUserID];
password = [defaults objectForKey:kPassword];
NSString *response = [cHandle doSearch:@"" :userID :[cHandle hashPass:password]];
listData = (NSMutableArray*)[cHandle parseSearch:response];
self.view.autoresizesSubviews = YES;
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[listTable reloadData];
[super viewDidLoad];
}
-(void)viewWillAppear:(BOOL)animated
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
userID = [defaults objectForKey:kUserID];
password = [defaults objectForKey:kPassword];
//initiate the connection handler, get the json response
cHandle = [ConnectHandler new];
NSString *response = [cHandle doSearch:@"": userID :[cHandle hashPass:password]];
listData = (NSMutableArray*)[cHandle parseSearch:response];
//[listTable reloadData];
[response release];
[super viewWillAppear:animated];
}
-(void)viewWillDisappear:(BOOL)animated{
[listData release];
[listTable release];
[super viewWillDisappear:animated];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return YES;
}
- (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.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
#pragma mark -
#pragma mark Search View
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
listData = nil;
[listTable reloadData];
query = searchBar.text;
[searchBar resignFirstResponder];
[listData removeAllObjects];
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
searchBar.text = @"";
[listTable reloadData];
[searchBar resignFirstResponder];
query = searchBar.text;
[listData removeAllObjects];
[self loadSearch:query];
}
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)searchText {
listData = nil;
[listTable reloadData];
query = searchBar.text;
[listData removeAllObjects];
[self loadSearch:query];
}
-(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
[listTable reloadData];
}
-(void)loadSearch:(NSString *)q{
self.editing = YES;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
userID = [defaults objectForKey:kUserID];
password = [defaults objectForKey:kPassword];
NSString *response = [cHandle doSearch:q :userID :[cHandle hashPass:password]];
listData = (NSMutableArray*)[cHandle parseSearch:response];
[listTable reloadData];
for (UITableViewCell *cell in [listTable visibleCells]) {
NSIndexPath *cellIndexPath = [listTable indexPathForCell:cell];
[listTable cellForRowAtIndexPath:cellIndexPath];
}
[response release];
}
- (void)dealloc {
[listData release];
[cHandle release];
[super dealloc];
}
#pragma mark -
#pragma mark Table View Data Source Methods
-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section{
return [listData count];
}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
static NSString *cellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil){
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
}
row = [indexPath row];
if (row >= [listData count]){
cell.textLabel.text = @"";
}else {
NSMutableString *cellText = [[NSMutableString alloc] initWithString:[[listData objectAtIndex:row] objectAtIndex:0]];
[cellText appendString:@", "];
[cellText appendString:[[listData objectAtIndex:row] objectAtIndex:1]];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.text = cellText;
[cellText release];
}
return cell;
}
-(UITableViewCellEditingStyle)tableView:(UITableView*)tableView editingStyleForRowAtIndexPath:(NSIndexPath*)indexPath
{
if (self.editing && indexPath.row == ([listData count]))
return UITableViewCellEditingStyleInsert;
else {
return UITableViewCellEditingStyleDelete;
}
}
-(void)tableView:(UITableView*)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath*)indexPath {
[listTable beginUpdates];
if (editingStyle == UITableViewCellEditingStyleDelete)
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setUserInteractionEnabled:NO];
cell.selected = NO;
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else {
}
[listTable endUpdates];
}
-(BOOL)tableView:(UITableView*)tableView canMoveRowAtIndexPath:(NSIndexPath*)indexPath
{
return YES;
}
@end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在您的代码中,似乎在字符串上调用了一个方法,而不是其他方法。尝试调试您的应用程序,在 cellForRowAtIndexPath 中放置一个断点。
It seems in your code a method is called on string instead of something else. Try to debug your application put a breakpoint in cellForRowAtIndexPath.
首先,引用插座的 uitableview 不应连接到数组,您必须将其连接到 uitableview。接下来,表视图的日期源和委托也应该设置为实现它们的类。
在 viewDidLoad 上,您必须在 uitableview 上调用 reloadData。这样,表格视图将在需要滚动之前更新。另外粘贴一些代码,以便调试其他问题。
First of all uitableview referencing outlet should not be connected to the array, you have to connect it to a uitableview. Next the datesource and delegate for the tableview should also be set to the class implementing them.
On viewDidLoad you have to call reloadData on the uitableview. This way the tableview will be updated before scrolling is needed. Also paste some more code so that the other problems can be debugged.