self.fetchedResultsController正在抛出EXC_BAD_ACCESS而_fetchedResultsController正常工作

时间:2014-02-12 06:46:36

标签: ios objective-c core-data nsfetchedresultscontroller

my.h:

@property(nonatomic, retain) NSManagedObjectContext *context;
//Managed Object Context of CoreData. Passed from AppDelegate

@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
//FetchedResultsController for managing fetched objects from coreData.

my.m:

- (NSNumber *) customMethod
{

    NSError *error;
    if ([[self fetchedResultsController] performFetch:&error]) 
    {
      return @1;
    }
    else
    {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    }
    return @0;
}

- (NSFetchedResultsController *)fetchedResultsController
{

    if (self.fetchedResultsController != nil)  //Here it throws EXC_BAD_ACCESS(code=2)
      //If used _fetchedResultsController, works fine
    {
        return self.fetchedResultsController;
    }

    //custom code to create FetchResultController.

   return _fetchedResultsController;

}

据我所知,self.var& _var是:

  • self.var是一个调用getter&amp ;;的访问器引用。设定器。
  • _var是一个直接访问器引用,它跳过调用getter&设定器。

我无法从这个理由中找到我的问题的线索。任何人都可以对这个场景有所了解吗?

3 个答案:

答案 0 :(得分:2)

您的自定义方法声明返回void,但您返回一个指向NSNumber的指针。当您的方法返回时,此对象将被释放,并且指针将无效。

自。 fetchedResultsController成为[self fetchedResultsController]。所以你递归地调用这个方法。在您的访问器中,您应该访问_fetchedResultsController实例变量,而不是使用点语法调用该方法。

你应该这样做:

- (NSFetchedResultsController *)fetchedResultsController
{

    if (_fetchedResultsController != nil)  //Here it throws EXC_BAD_ACCESS(code=2)
      //If used _fetchedResultsController, works fine
    {
        return _fetchedResultsController;
    }

    //custom code to create FetchResultController.

   return _fetchedResultsController;

}

顺便说一句,如果你不清楚这一点,使用核心数据可能会是一项非常艰巨的任务,尽管你非常勇敢:)。

答案 1 :(得分:1)

尝试在nil检查中使用_fetchedResultsController以及在非nil内返回。否则你反复调用你定义的方法而不是属性!

确保您了解属性如何生成setter和getter。

答案 2 :(得分:1)

我发现这是一个非常有启发性的错误。基本上,

 - (NSFetchedResultsController *)fetchedResultsController {}

是fetchedResultsController属性的getter。和

if(self.fetchedResultsController) {}

是一个测试,看看是否设置了fetchedResultsController(!= nil)。这通常是我们测试以查看属性是否已设置的方式。我们问吸气剂是否不是零。但问题是我们试图在fetchedResultsController的getter中做这个!因此,我们询问getter是否已设置并运行我们的请求所在的方法。它运行getter并再次到达测试,询问getter是否已设置fetchedResultsController属性。这个循环会无限期地继续下去,但是编译器很友好,并且在循环一段时间之后会崩溃。询问访问者是否已设置fetchedResultsController是没有用的,而不是在getter中。因为如果设置了变量,它将设置其后备实例变量,我们要求它。 enter image description here

通常我们不应该直接访问ivars。这是一个例外。初始化是另一个例外。原因是如果自己还不存在,我们就不应该提到自我。无论如何,我发现它很有启发性。