2010-09-19 99 views
1

我有一个UITabBarController。其中一个选项卡显示应用程序“书签”,这些书签基本上是保存到核心数据(SQLLite)数据库的搜索类型。奇怪的EXC_BAD_ACCESS,我做错了什么?

当我加载我的应用程序时,转到书签视图(bookmarksViewController),它在我的appDelegate(getBookmarks)中加载一个函数,并在表中显示结果。这是完美的,可以在视图之间切换,其他视图中的预制件搜索切换回来。没问题。它每次加载内容。 但是,当我加载搜索视图并添加一个新书签,然后切换回书签视图时,它会显示错误消息“EXC_BAD_ACCESS”。 我不知道为什么以及如何解决这个问题。

这是我的代码:
bookmarksViewController.m

[...] 
- (void)viewDidLoad { 
    [super viewDidLoad]; 

theBookmarks = nil; 

    // Set up the edit and add buttons. 
    self.navigationItem.rightBarButtonItem = self.editButtonItem; 

[self setTitle:NSLocalizedString(@"Bookmarks", @"bookmarksViewController")]; 
} 

- (void)viewWillAppear:(BOOL)animated { 
if (theBookmarks != nil) 
{ 
    NSLog(@"Release it!"); 
    [theBookmarks release]; 
} 

NSLog(@"Appear 1"); 

stationenAppDelegate *stationen = (stationenAppDelegate *)[[UIApplication sharedApplication]delegate]; 

NSLog(@"Appear 1 - stage 2"); 

theBookmarks = [[stationen getBookmarks] retain]; 

NSLog(@"Appear 2"); 

    [super viewWillAppear:animated]; 
} 
[...] 

myAppDelegate.m

[...] 
/** 
* Bookmarks 
* 
* Type definition 
* 1: Station search 
* 2: Train search 
* 3: Interuption search 
*/ 

- (NSMutableArray*)getBookmarks 
{ 
NSLog(@"check 1"); 

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 

NSEntityDescription *entity = [NSEntityDescription entityForName:@"bookmarks" 
      inManagedObjectContext:self.managedObjectContext]; 
[fetchRequest setEntity:entity]; 

NSLog(@"check 2"); 

NSError *error; 
NSArray *items = [[self.managedObjectContext 
     executeFetchRequest:fetchRequest error:&error] retain]; 
NSMutableArray *returnArray = [[[NSMutableArray alloc] initWithArray:items] retain]; 

NSLog(@"check 4"); 

[fetchRequest release]; 

return returnArray; 
} 

- (void)addBookmark:(bookmarks_object*)theBookmark 
{ 
BOOL exists = [self checkIfBookmarkExistsUsingBookmark:theBookmark]; 

if(!exists) 
{ 
    bookmarks *saveBookmark = (bookmarks *)[NSEntityDescription insertNewObjectForEntityForName:@"bookmarks" 
        inManagedObjectContext:self.managedObjectContext]; 

    [saveBookmark setStation_from:theBookmark.station_from]; 
    [saveBookmark setStation_to:theBookmark.station_to]; 
    [saveBookmark setAddDate:[[NSDate alloc] init]]; 
    [saveBookmark setSort:theBookmark.sort]; 
    [saveBookmark setPlace:[[NSNumber alloc] initWithInt:([[self getBookmarks] count]+1)]]; 
    [saveBookmark setName:([theBookmark.type isEqualToString:@"1"] || [theBookmark.type isEqualToString:@"2"] ? theBookmark.station_from : [[NSString alloc] initWithFormat:@"%@ -> %@", theBookmark.station_from, theBookmark.station_to])]; 
    [saveBookmark setType:theBookmark.type]; 

    [self saveAction]; 
    [saveBookmark release]; 
} 
else { 
    NSLog(@"No need to add, %@ already exists!", theBookmark.station_from); 
} 
} 

- (BOOL)checkIfBookmarkExistsUsingBookmark:(bookmarks_object*)theBookmark 
{ 
// Get the categories 
NSArray *historyArray = [self getBookmarks]; 

BOOL exists = NO; 

for(bookmarks *dbHistory in historyArray) 
{ 
    if ([theBookmark.type isEqualToString:@"1"] || [theBookmark.type isEqualToString:@"2"]) 
    { 
    if([[dbHistory station_from] isEqualToString:theBookmark.station_from]) 
    { 
    exists = YES; 
    continue; 
    } 
    } 
    else if ([theBookmark.type isEqualToString:@"3"]) 
    { 
    if([[dbHistory station_from] isEqualToString:theBookmark.station_from] && 
     [[dbHistory station_to] isEqualToString:theBookmark.station_to]) 
    { 
    exists = YES; 
    continue; 
    } 
    } 
    else { 
    NSLog(@"Error! Unknown type!"); 
    return NO; 
    } 
} 

return exists; 
} 
[...] 

堆栈跟踪(流程:打开应用,负载书签视图中切换到搜索查看,添加书签,切换回)

2010-09-19 13:51:54.554 stationen[7256:207] Appear 1 
2010-09-19 13:51:54.555 stationen[7256:207] Appear 1 - stage 2 
2010-09-19 13:51:54.555 stationen[7256:207] check 1 
2010-09-19 13:51:54.560 stationen[7256:207] check 2 
2010-09-19 13:51:54.562 stationen[7256:207] check 4 
2010-09-19 13:51:54.562 stationen[7256:207] Appear 2 
2010-09-19 13:52:26.669 stationen[7256:207] check 1 
2010-09-19 13:52:26.670 stationen[7256:207] check 2 
2010-09-19 13:52:26.671 stationen[7256:207] check 4 
2010-09-19 13:52:26.671 stationen[7256:207] No need to add, 230 already exists! 
2010-09-19 13:52:30.509 stationen[7256:207] Release it! 
2010-09-19 13:52:30.510 stationen[7256:207] Appear 1 
2010-09-19 13:52:30.510 stationen[7256:207] Appear 1 - stage 2 
Program received signal: “EXC_BAD_ACCESS”. 
+1

请设置断点并检查[stationen getBookmarks]的返回结果是否为零或者是否为零...以及您为什么保留这么多的原因? – 2010-09-19 12:02:52

+2

你有没有设置NSZombieEnabled?它可以帮助追踪这些错误:http://iphonedevelopertips.com/debugging/tracking-down-exc_bad_access-errors-with-nszombieenabled.html – Mark 2010-09-19 12:07:14

+0

不,但我会看看。 Thnx – 2010-09-19 13:20:55

回答

0

问题是appDelegate以某种方式在分配它和使用它的时间之间释放。 我向它添加一个保留,然后立即释放它。

按照Mark的建议使用NSZombieEnabled发现它。谢谢!

+0

哦,我没有刷新页面,我评论了这篇文章:D对不起! – matteodv 2010-09-19 13:41:49

+0

Np。它只是有点怪异。我添加了其他搜索视图,同样的事情发生在这里。但现在我保留了这个对象。代码''stationenAppDelegate * stationen =(stationenAppDelegate *)[[[UIApplication sharedApplication] delegate] retain];''直接解除分配。 – 2010-09-19 20:25:58

+1

您不应该在任何地方保留或释放应用程序委托。如果您有一个指向应用程序委托的属性,那么在属性声明中将其设置为'assign'而不是'release'。 – TechZen 2010-09-20 12:23:42

0

您是否尝试使用调试器查看错误的位置?
在Xcode中打开调试器,然后使用断点构建应用程序。在模拟器中执行所有步骤来重现错误。
当您发现错误时,调试器会在应用程序崩溃之前停止应用程序,并且您会在调试器视图中看到您实现的方法...其中一个或多个将以黑色突出显示/写入。在这些方法中有一个错误。点击方法,你会看到错误的位置,然后你就可以修改该代码来解决错误...

希望这能帮助你! :)

+0

是的,我有......那就是没有成功的观点。我在“check 1”处放置了断点,并在书签视图中添加了“getBookmarks”函数的调用。它似乎在我之间死亡。 – 2010-09-19 13:20:21

+1

不幸的是,我不是专家,因为在iPhone开发之前我从未开发过。在网上阅读,EXC_BAD_ACCESS是一个可以使用NSZombieEnabled解决的常见问题,就像Mark说的那样。你可以看看这些帖子:http://www.codza.com/how-to-debug-exc_bad_access-on-iphone和http://www.touch-code-magazine.com/how-to-debug -exc_bad_access /希望这可以帮助你! ;) – matteodv 2010-09-19 13:38:38