所以我很难找到我的程序崩溃的原因。到目前为止,我有一个主屏幕,它带有两个标签的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中使用zombies工具来找出问题所在。我运行它,它说“一个Objective-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指的是什么。
有关找到问题所在位置的任何帮助表示赞赏。感谢
---- ---- EDIT
我认为问题出在这两个类的某个地方,我尝试发布代码中更相关的部分。
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);
}
}
}];
}
答案 0 :(得分:1)
所以我觉得我找到了实际答案。我发现"修复"当我开始做不同的视图控制器序列时,我做的并没有实际工作。它看起来也很奇怪,所以在再次查看我的代码后,看起来实际的问题是我没有重置我的代表。
答案 1 :(得分:1)
Swift iOS:Zombie UIKit [UINavigationController _startCustomTransition:] 我正在使用以下生成错误的代码:
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.delegate = self
}// end viewDidLoad
但是一旦我在视图中更改了委托,它就会开始工作而不会发生任何崩溃
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.delegate = self
}