NSFetchedResultsController谓词有点太实时......?

时间:2010-08-04 04:01:50

标签: objective-c cocoa-touch core-data

所以我有一个NSFetchedResultsController,我在ViewDidLoad上使用已加载的appdelegate传递的managedobjectcontext激活。

我在一些字段上放了一个谓词,让它称之为“sectionNumber”,并说它在我的谓词中需要等于1。

NSFetchResultsController正常工作,直到我向MOContext添加一个新对象...

我使用MyMO * newObj = [NSEntityDescription insertnewentity] ...

开始填写不同的字段 [newobj setName:@“me”]; [newobj setAge:12];

等...

一旦我把[newobj setSectionNumber:1] - 它在那个瞬间找到它并导致应用程序崩溃,导致EXC_BAD_ACCESS的不同奇怪错误。

所有这些都发生在MAIN THREAD上。

任何想法为什么?怎么可以绕过那个?

更新: 它只发生在我使用我的saveMOC方法时,该方法是在我生成的NSXMLParser特定线程结束时调用的。使用[self performSelectorOnMainThread]成功解析saveMOC ....如果我刚刚通过ViewDidLoad添加了额外的managedobject(只是为了检查天气,这与线程有关),问题不会发生。

因此,即使选择器应该在主线程上运行,这显然也是新线程的一部分。

更新#2: 这是我为XML Parser生成的线程:

- (void)getAndParseXML {     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

DLog(@"Online storage");
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:theUrl];

XMLTranslator *translator = [[XMLTranslator alloc] init];
[parser setDelegate:translator];
if ([parser parse]) {
        //success call MOC change routine on main thread
    DLog(@"success parsing");
    [self performSelectorOnMainThread:@selector(saveMOC:) withObject:translator waitUntilDone:NO];
} else {
    DLog(@"error: %@",[parser parserError]);
}


[parser setDelegate:nil];
[parser release];
DLog(@"XML parsing completed");
[pool release];

}

然后这是我的saveMOC:

-(void)saveMOC:(XMLTranslator*)translator {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
for (NSDictionary *dict in [translator retrievedData]) {

    APost *newPost = [NSEntityDescription insertNewObjectForEntityForName:@"APost"
                                                     inManagedObjectContext:managedObjectContext];

    //parse time into NSDate
    [newPost setTime:[formatter dateFromString:[dict objectForKey:@"time"]]];


    //author, category, description
    [newPost setAuthor:[dict objectForKey:@"author"]];
    [newPost setCategory:[dict objectForKey:@"category"]];
    [newPost setContent:[dict objectForKey:@"description"]];

    //create a post id so that the validation will be alright
    [newPost setPostid:[NSNumber numberWithInteger:[[dict objectForKey:@"postid"] integerValue]]];


    [newPost setSectionDesignator:sectionDesignator];

}

这个saveMoc方法继续并且有一个[managedobjectcontext save:& error]等等...但它与我们的情况不相关,因为我的方法崩溃我发现通过在我设置的点上一行接一条地评论sectionDesignator,因为它等于我的NSFetchedResultsController中的当前谓词。

3 个答案:

答案 0 :(得分:1)

问题很可能出在NSFetchedResultsController委托方法中或缺少它。

当您向任何上下文添加新对象然后保存上下文时,会更改在任何线程上触发FRC的持久存储以开始更新tableview。所有索引路径都会更改,尤其是在为用作sectionNameKeyPath的属性设置值时。如果表在更新期间请求单元格,则会导致崩溃,因为该表可以通过插入新的托管对象来请求索引路径中的单元格无效。

您需要确保实现FRC的委托方法,并在FRC更改其所有索引路径时向表发送beginUpdate消息以冻结它。

答案 1 :(得分:1)

我很遗憾地承认这个问题一直是释放一个数组,该数组在FRC中使用的获取请求中保存了排序描述符。

看了很多例子我释放了那个数组,不像我用[NSArray arrayWithObject:.............]创建数组的例子;

每次多次访问获取请求时都会出现过度释放。

  • 随意关闭此内容。谢谢大家的帮助。当彼得写下来看整个堆栈而不只是一个框架时,我发现了这一点。

答案 2 :(得分:0)

我进一步分析了这个问题,并意识到它发生在循环中。

我进一步明白,只有当我有多个对象时才会发生这种情况,这意味着一个FRC在一个对象插入MOC并尝试返回到for循环后接管,它会尝试访问一个对象或一个引用那不存在。我还没有找到导致它的对象以及如何正确保留它。

有什么建议吗?

请考虑以下事项:

for (int i=0; i<2; i++) {
    NSLog(@"%i",i);
    APost *thePost = [NSEntityDescription insertNewObjectForEntityForName:@"HWBPost" inManagedObjectContext:managedObjectContext];
    [thePost setCategory:@"CAAA"];
    [thePost setContent:@"SSSSSS"];
    [thePost setSectionDesignator:sectionDesignator];       
}

如果我将for循环更改为i&lt; 1意味着它只运行一次,那么应用程序不会崩溃。只要有多个对象插入,应用程序就会崩溃。