如何在同步函数调用中处理异步回调?

时间:2012-12-25 17:41:51

标签: iphone objective-c ios callback objective-c-blocks

我有一个方法,它在回调中异步返回一个对象(例如UserProfile)。

基于此UserProfile对象,某些代码会计算UITableViewCell是否可编辑:

我创建了以下代码,但遗憾的是它无法正常工作。

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{        
    Entry *entry = [[self.feed entries] objectAtIndex:[indexPath row]];
    typedef BOOL (^BOOLBlock)(id);

    BOOLBlock bar = ^BOOL (id p) {
        if (p) {
            UserProfile *user = (UserProfile *) p;
            NSEnumerator *e = [[entry authors] objectEnumerator];
            id object;
            while (object = [e nextObject]) {
                if ([[object name] isEqualToString:[[[user authors] objectAtIndex:0] name]])
                    return TRUE;
            }
            return FALSE;
        } 
        else {
            return FALSE;
        }
    };

    [[APPContentManager classInstance] userProfile:bar];    
}

在最后一行,它表示不兼容的块指针类型发送

'__strong BOOLBlock' (aka 'BOOL (^__strong)(__strong id)') to parameter of type 'void (^)(UserProfile *__strong)'

APPContentManager.h

-(void)userProfile:(void (^)(UserProfile *user))callback;

1 个答案:

答案 0 :(得分:3)

-userProfile:方法不期望你的BOOLBlock类型 - 它不负责返回任何东西。你想在这里使用信号量,但是你应该记住Till关于-tableView:canEditRowAtIndexPath:的预期同步性的评论 - 如果你的userProfile:方法需要一段时间,你肯定应该预先知道这个可编辑性信息。

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {        
    Entry *entry = [[self.feed entries] objectAtIndex:[indexPath row]];
    dispatch_semaphore_t sema = dispatch_semaphore_create(0);
    __block BOOL foundAuthor = NO;

    [[APPContentManager classInstance] userProfile:^(UserProfile *user) {
        NSEnumerator *e = [[entry authors] objectEnumerator];
        id object;
        while (object = [e nextObject]) {
            if ([[object name] isEqualToString:[[[user authors] objectAtIndex:0] name]]) {
                foundAuthor = YES;
                break;
            }
        }
        dispatch_semaphore_signal(sema);
    }];
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
    dispatch_release(sema);

    return foundAuthor;
}