首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UIManagedDocument单例代码openWithCompletionHandler调用了两次,但崩溃

UIManagedDocument单例代码openWithCompletionHandler调用了两次,但崩溃
EN

Stack Overflow用户
提问于 2012-11-21 03:00:18
回答 2查看 1.2K关注 0票数 6

我在Core Data with a Single Shared UIManagedDocument上使用了Justin Driscoll的实现。我的iphone应用程序本来一切都很好,直到我把它移到了iPad故事板和ipad应用程序的拆分视图控制器上。问题是openwithCompletionHandler被调用了两次,一次是在viewDidLoad的主视图中,另一次是在我的细节视图viewWillLoad中。这些调用都是快速连续的,当第二次调用单例应用程序的performWithDocument方法(如下所示)时,文档仍在UIDocumentStateClosed中,因此应用程序崩溃。我看了e_x_p对post iOS5.1: synchronising tasks (wait for a completion)的回答,但是@sychronized在这种情况下不会工作,因为下面的performWithDocument是在同一个线程上调用的。如何防止对openwithCompletionHandler的多个调用?我能想到的防止这种情况的唯一方法是暂停上面的一个调用的执行,直到我确定UIDocumentStateNormal为真,然后释放。不过,这会冻结主UI线程,这是不好的。但是,在不冻结UI的情况下,最好的方法是什么呢?

在UIManagedDocumentSingleton代码中:

代码语言:javascript
复制
- (void)performWithDocument:(OnDocumentReady)onDocumentReady
{
    void (^OnDocumentDidLoad)(BOOL) = ^(BOOL success)
    {
        onDocumentReady(self.document);
    };

    if (![[NSFileManager defaultManager] fileExistsAtPath:[self.document.fileURL path]])
    {
        //This should never happen*******************
        [self.document saveToURL:self.document.fileURL
                forSaveOperation:UIDocumentSaveForCreating
               completionHandler:OnDocumentDidLoad];

    } else if (self.document.documentState == UIDocumentStateClosed) {
        [self.document openWithCompletionHandler:OnDocumentDidLoad];
    } else if (self.document.documentState == UIDocumentStateNormal) {
        OnDocumentDidLoad(YES);
    }
}
EN

回答 2

Stack Overflow用户

发布于 2013-04-17 04:17:57

这很有趣,而且肯定是我代码中的一个缺陷(对不起!)。我的第一个想法是将串行队列作为属性添加到文档处理程序类中,并对其执行检查。

代码语言:javascript
复制
self.queue = dispatch_queue_create("com.myapp.DocumentQueue", NULL);

然后在performWithDocument中:

代码语言:javascript
复制
dispatch_async(self.queue, ^{
    if (![[NSFileManager defaultManager] fileExistsAtPath... // and so on
});

但那也行不通..。

您可以在调用saveToURL时设置BOOL标志,并在回调中将其清除。然后,如果正在创建文件,您可以检查该标志,并在稍后使用performSelectorAfterDelay再次调用performWithDocument。

票数 1
EN

Stack Overflow用户

发布于 2012-11-21 13:21:04

numberOfRowsInSection:cellForRowAtIndexPath:之间共享的代码块应该只调用一次。numberOfRowsInSection总是在tableView尝试呈现单元格之前被调用,因此您应该创建一个NSArray对象,您可以将fetch请求的结果存储到该对象中,然后在呈现单元格时使用此数组:

代码语言:javascript
复制
@implementation FooTableViewController {
    NSArray *_privateArray;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    [[UIManagedDocumentSingletonHandler sharedDocumentHandler] performWithDocument:^(FCUIManagedDocumentObject *document) {
        NSManagedObjectContext * context =  document.managedObjectContext;

        NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"FCObject"];
        NSPredicate * searchStringPredicate = nil;
        if (searchFilterString)
        {
            searchStringPredicate = [NSPredicate predicateWithFormat:@"word BEGINSWITH[c] %@",searchFilterString];
        }
        request.predicate = searchStringPredicate;
        request.shouldRefreshRefetchedObjects = YES;
        NSError * error;
        _privateArray = [context executeFetchRequest:request error:&error];
        }];
    return _privateArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"FCCell";
    FCardCell *cell = (FCCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Configure the cell...
    FCManagedObject * fcc = [_privateArray objectAtIndex:indexPath.row];
    cell.isWordVisible.on = fcc.isUsed;
    cell.fWord.text = fcc.word;
    return cell;
}

我不确定您是否需要对NSArray做一些特殊的操作来将其设置在块中(就像__block一样)。

这样做的主要原因是,您需要确保用于确定行数的数据集的100%大小与您创建单元格时的大小相同。如果它们不匹配,那么您将崩溃。此外,由于您没有块,所以现在不需要分派来进行UITableViewCell更新。

最后,如果UIDocumentStateClosed造成了问题,您应该将它们从NSFetch结果中过滤出来(附加谓词,如果需要,请参阅NSCompoundPredicate ),或者让代码在cellForRowAtIndexPath:中更好地处理它们

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13480211

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档