所以我很困惑,试图找出为什么我的程序崩溃了。到目前为止,我有一个主屏幕,该屏幕转到带有两个选项卡的UITabBar,每个选项卡都有UITableViews。在第二个选项卡上,我有一个自定义单元格,如果用户单击它,则该单元格应提供更多详细信息。所有这些都在UINavigationController中。当我进入具有表单元格详细信息的视图控制器时,按回车,然后再次按回车(我应该在主屏幕上),程序将在此处崩溃,并显示EXC_BAD_ACCESS(代码= 1):
int main(int argc, char * argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([RaceMeAppDelegate class])); //EXC_BAD_ACCESS }
}
通过查看其他帖子,我尝试在Xcode中使用僵尸工具来找出问题所在。我运行了它,并说:“将目标C消息发送到地址为0x16f19370的已释放的“ MatchCellDetailsViewController”对象(僵尸)。日志如下所示:
# Event Type ∆ RefCt RefCt Timestamp Responsible Library Responsible Caller
0 Malloc +1 1 00:14.422.351 UIKit -[UIClassSwapper initWithCoder:]
1 Retain +1 2 00:14.430.802 UIKit UINibDecoderDecodeObjectForValue
2 Retain +1 3 00:14.431.402 UIKit -[UIRuntimeConnection initWithCoder:]
3 Retain +1 4 00:14.431.488 UIKit -[UIRuntimeConnection initWithCoder:]
4 Retain +1 5 00:14.431.977 UIKit UINibDecoderDecodeObjectForValue
5 Retain +1 6 00:14.432.136 UIKit UINibDecoderDecodeObjectForValue
6 Retain +1 7 00:14.432.310 Foundation -[NSObject(NSKeyValueCoding) setValue:forKeyPath:]
7 Retain +1 8 00:14.432.639 UIKit -[UINib instantiateWithOwner:options:]
8 Release -1 7 00:14.432.964 UIKit -[UINibDecoder finishDecoding]
Release (2) -2 00:14.433.013 UIKit -[UINibDecoder finishDecoding]
10 Release -1 5 00:14.433.134 UIKit -[UINibDecoder finishDecoding]
11 Release -1 4 00:14.433.176 UIKit -[UIRuntimeConnection dealloc]
12 Release -1 3 00:14.433.341 UIKit -[UIRuntimeConnection dealloc]
14 Retain +1 3 00:14.434.055 UIKit -[UIStoryboardSegue initWithIdentifier:source:destination:]
Retain/Release (2) 00:14.434.138 RaceMe -[ReceivedTabTableViewController prepareForSegue:sender:]
17 Retain +1 4 00:14.436.369 UIKit -[UIViewController _addChildViewController:performHierarchyCheck:notifyWillMove:]
Retain/Autorelease/Release (3) 00:14.437.924 UIKit -[UINavigationController topViewController]
Retain/Autorelease/Release (3) 00:14.438.033 UIKit -[UINavigationController topViewController]
Retain/Release (2) 00:14.438.158 UIKit -[UINavigationController pushViewController:transition:forceImmediate:]
Retain/Autorelease/Release (3) 00:14.465.975 UIKit -[UINavigationController topViewController]
25 Retain +1 9 00:14.466.037 libsystem_blocks.dylib _Block_object_assign
26 Retain +1 10 00:14.467.423 UIKit -[UINavigationController topViewController]
27 Autorelease 00:14.467.430 UIKit -[UINavigationController _startDeferredTransitionIfNeeded:]
28 Retain +1 11 00:14.467.467 UIKit -[UINavigationController topViewController]
29 Autorelease 00:14.467.475 UIKit -[UINavigationController _startCustomTransition:]
30 Retain +1 12 00:14.477.542 UIKit -[UINib instantiateWithOwner:options:]
31 Retain +1 13 00:14.484.362 UIKit -[UINib instantiateWithOwner:options:]
32 Retain +1 14 00:14.484.481 UIKit -[UINib instantiateWithOwner:options:]
33 Retain +1 15 00:14.484.582 UIKit +[UIProxyObject addMappings:forCoder:]
34 Retain +1 16 00:14.493.202 UIKit -[UIProxyObject initWithCoder:]
Retain/Release (12) 00:14.493.229 UIKit -[UIRuntimeConnection initWithCoder:]
Retain (4) +4 00:14.494.155 UIKit -[UIRuntimeConnection initWithCoder:]
40 Retain +1 22 00:14.498.045 UIKit -[UIProxyObject initWithCoder:]
46 Release -1 26 00:14.505.411 UIKit -[UINib instantiateWithOwner:options:]
Release (4) -4 00:14.506.686 UIKit -[UINibDecoder finishDecoding]
Release (4) -4 00:14.507.340 UIKit -[UIRuntimeConnection dealloc]
61 Release -1 11 00:14.509.718 Foundation -[NSAutoreleasePool drain]
62 Retain +1 12 00:14.513.293 UIKit -[UINavigationController topViewController]
63 Autorelease 00:14.513.308 UIKit -[UINavigationController _startCustomTransition:]
Retain/Release (2) 00:14.513.330 UIKit -[UINavigationController _startCustomTransition:]
66 Retain +1 13 00:14.513.399 UIKit -[UINavigationController topViewController]
67 Autorelease 00:14.513.407 UIKit -[UINavigationController _startCustomTransition:]
68 Retain +1 14 00:14.513.477 UIKit -[UINavigationController _startCustomTransition:]
69 Release -1 13 00:14.513.642 UIKit -[UINavigationController _startCustomTransition:]
Retain/Autorelease/Release (3) 00:14.514.475 UIKit -[UINavigationController topViewController]
72 Retain +1 15 00:14.719.975 libsystem_blocks.dylib _Block_object_assign
Retain/Autorelease/Release (3) 00:14.722.535 UIKit -[UINavigationController topViewController]
Retain/Release (2) 00:14.723.110 UIKit -[UIResponder becomeFirstResponder]
77 Release -1 15 00:14.762.974 libsystem_blocks.dylib _Block_release
Release (3) -3 00:15.145.440 QuartzCore CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*)
84 Release -1 8 00:15.146.309 UIKit _wrapRunLoopWithAutoreleasePoolHandler
87 Release -1 5 00:15.147.134 UIKit -[UIStoryboardSegue dealloc]
88 Release -1 4 00:15.147.183 UIKit _wrapRunLoopWithAutoreleasePoolHandler
89 Release -1 3 00:15.147.322 UIKit -[UIStoryboardScene dealloc]
90 Retain +1 4 00:15.385.010 UIKit -[UINavigationController topViewController]
91 Autorelease 00:15.385.017 UIKit -[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:]
Retain/Autorelease/Release (3) 00:15.429.329 UIKit -[UINavigationController topViewController]
94 Retain +1 6 00:15.431.214 UIKit -[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:]
Release (2) -2 00:15.431.373 UIKit -[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:]
97 Release -1 3 00:15.433.236 UIKit __destroy_helper_block_119
98 Release -1 2 00:15.433.615 GraphicsServices GSEventRunModal
Retain/Autorelease/Release (3) 00:15.792.024 UIKit -[UINavigationController topViewController]
Retain/Autorelease/Release (3) 00:15.792.321 UIKit -[UINavigationController topViewController]
Retain/Autorelease/Release (6) 00:15.792.807 UIKit -[UINavigationController topViewController]
Retain/Release (2) 00:15.792.878 UIKit -[UINavigationController _popViewControllerWithTransition:allowPoppingLast:]
Release/Retain (2) 00:15.792.899 UIKit _popViewControllerNormal
Retain/Release (2) 00:15.793.576 UIKit _popViewControllerNormal
Retain/Release (8) 00:15.824.455 UIKit -[UINavigationController _startCustomTransition:]
124 Retain +1 4 00:16.554.694 UIKit -[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:]
126 Retain +1 4 00:16.555.120 UIKit -[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:]
128 Release -1 2 00:16.555.354 UIKit -[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:]
130 Release -1 0 00:16.559.291 UIKit __destroy_helper_block_119
131 Zombie -1 00:18.098.937 UIKit -[UINavigationController _startCustomTransition:]
我尝试查看是否在我不应该调用的地方调用MatchCellDetailsViewController,但是找不到使用该类的地方,这会导致问题。第二个选项卡是MatchCellDetailsViewController的委托,以便我可以向后传递数据,但是除此之外,我认为我没有进行任何错误的调用。我不太确定_startCustomTransition指的是什么。
感谢您对定位问题所在的任何帮助。谢谢
- - 编辑 - -
我认为问题出在这两个类中,我尝试过发布代码中更相关的部分。
ReceivedTabBarViewController.m(主屏幕转到此)
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.tableView reloadData]; //necessary to reload if user switches between tabs
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadMatchesWithCallback:^(NSArray *matches) {
self.matches = matches;
self.matchesMutable = [NSMutableArray arrayWithArray:self.matches];
[self.activityIndicator startAnimating];
if ([self.matches count] == 0) { [self.activityIndicator stopAnimating]; }
for (GKTurnBasedMatch *match in self.matches) {
//Gets the match data
[self loadAndDisplayMatchDataWithCallback:match callback:^(NSData *matchData) {
RaceMeGame *updatedGame = [NSKeyedUnarchiver unarchiveObjectWithData:matchData];
NSString *matchDataString = [NSString stringWithFormat:@"%@ %@ %@ %d", updatedGame.matchDistance, updatedGame.status, updatedGame.score, updatedGame.numberOfTurns];
[self.matchWithMatchData setObject:matchDataString forKey:match.matchID];
NSLog(@"Match data: %@", matchDataString);
NSLog(@"Current number of turns: %d", updatedGame.numberOfTurns);
//Converts the matchID to a GKTurnBasedMatch
[self retrieveMatch:match.matchID callback:^(GKTurnBasedMatch *match) {
GKTurnBasedParticipant *currentPlayerInMatch = [match currentParticipant];
NSArray *currentPlayerIDs = [[NSArray alloc] initWithObjects:currentPlayerInMatch.playerID, nil];
//Converts a player ID to a player's alias
[self retrievePlayerAliases:currentPlayerIDs callback:^(NSArray *players) {
[self.currentPlayerTurnAliasList addObject:((GKPlayer*)[players firstObject]).alias];
if ([self.currentPlayerTurnAliasList count] == [self.matches count]) {
[self.tableView reloadData];
[self.activityIndicator stopAnimating];
}
}];
}];
}];
}
}];
}
- (void)removeReceivedChallenge:(NSInteger)index
{
GKTurnBasedMatch *match = [self.matchesMutable objectAtIndex:index];
//Remove the data from table
[self.matchWithMatchData removeObjectForKey:match.matchID];
[self.matchesMutable removeObjectAtIndex:(NSUInteger)index];
NSIndexPath *myIP = [NSIndexPath indexPathForRow:index inSection:0];
[self.tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:myIP] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
}
#pragma mark - MatchCellDetailsViewController Delegate
- (void)indexRemoveViewController:(MatchCellDetailsViewController *)controller didFinishRemovingIndex:(NSInteger)index
{
[self removeReceivedChallenge:index];
}
- (void)moveChallengeToCurrentViewController:(MatchCellDetailsViewController *)controller didFinishMoving:(GKTurnBasedMatch*)match
{
GlobalVars *globals = [GlobalVars sharedInstance];
RaceMeGame *updatedGame = [NSKeyedUnarchiver unarchiveObjectWithData:match.matchData];
NSArray *currentPlayerIDs = [[NSArray alloc] initWithObjects:match.currentParticipant.playerID, nil];
[self retrievePlayerAliases:currentPlayerIDs callback:^(NSArray *players) {
[globals.currentMatches setObject:[[NSDictionary alloc]
initWithObjectsAndKeys:updatedGame.status, ((GKPlayer*)[players firstObject]).alias, nil]
forKey:match.matchID];
if (![globals.currentMatchesHelper containsObject:match.matchID]) {
[globals.currentMatchesHelper addObject:match.matchID];
}
}];
}
#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"ShowReceivedChallengeDetails"]) {
MatchCellDetailsViewController *detailViewController = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
long row = [myIndexPath row];
//Distance-Status-Score-NumberOfTurns
NSString *tempMatchString = [self.matchWithMatchData objectForKey:((GKTurnBasedMatch *)[self.matchesMutable objectAtIndex:row]).matchID];
NSArray *tempMatchArrayData = [tempMatchString componentsSeparatedByString:@" "];
detailViewController.distance = [NSString stringWithFormat:@"Distance: %@", [tempMatchArrayData objectAtIndex:0]];
detailViewController.status = [NSString stringWithFormat:@"Game Status: %@", [tempMatchArrayData objectAtIndex:1]];
detailViewController.participant = [NSString stringWithFormat:@"Current Players Turn: %@", [self.currentPlayerTurnAliasList objectAtIndex:row]];
detailViewController.currentNumberOfTurns = [[tempMatchArrayData objectAtIndex:3] intValue];
detailViewController.match = [self.matchesMutable objectAtIndex:row];
detailViewController.rowSelected = (NSInteger)row;
detailViewController.delegate = self;
}
}
MatchCellDetailsViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.delegate = self;
self.distanceLabel.text = self.distance;
self.statusLabel.text = self.status;
self.currentPlayersLabel.text = self.participant;
}
- (IBAction)acceptInvite:(UIButton *)sender {
[self.match acceptInviteWithCompletionHandler:^(GKTurnBasedMatch *match, NSError *error) {
if (error) {
}
else {
if (self.currentNumberOfTurns == 1) {
//advance turn back to the other user
[GameCenterHelper sharedInstance].currentMatch = match;
NSLog(@"Advancing turn");
/***** Preparation to advance turn ******/
//Converting game to NSData and sending it as match data
if ([[GameCenterHelper sharedInstance].currentMatch.matchData bytes] == 0) {
NSLog(@"Match data not created yet, allocating and initializing it");
[GameCenterHelper sharedInstance].gameData = [[RaceMeGame alloc] init];
[[GameCenterHelper sharedInstance] advanceTurn];
NSInteger index = self.rowSelected;
NSLog(@"Index being passed: %d", index);
[self.delegate indexRemoveViewController:self didFinishRemovingIndex:index];
[self.delegate moveChallengeToCurrentViewController:self didFinishMoving:match];
} else {
[[GameCenterHelper sharedInstance] loadAndDisplayMatchDataWithCallback:[GameCenterHelper sharedInstance].currentMatch callback:^(NSData *matchData) {
[GameCenterHelper sharedInstance].gameData = [NSKeyedUnarchiver unarchiveObjectWithData:matchData];
[[GameCenterHelper sharedInstance] advanceTurn];
//Remove this cell from ReceivedChallengesVC
NSInteger index = self.rowSelected;
[self.delegate indexRemoveViewController:self didFinishRemovingIndex:index];
//Send the data to CurrentMatchesVC
//Moves the challenge that the player has accepted the invite to from ReceivedChallengesVC to CurrentChallengesVC
[self.delegate moveChallengeToCurrentViewController:self didFinishMoving:match];
}];
}
} else {
NSLog(@“Error: %@“, error);
}
}
}];
}
最佳答案
所以我想我找到了实际的答案。我发现,当我开始做一系列不同的视图控制器时,我所做的“修复”实际上没有用。看起来也很怪异,所以在再次查看我的代码后,看起来实际的问题是我没有重置我的委托人。