首页 \ 问答 \ 同步回调 - 阻止与GCD队列(Synchronization callbacks - block vs GCD queue)

同步回调 - 阻止与GCD队列(Synchronization callbacks - block vs GCD queue)

我是异步回调的新手,并且给出了不同的建议。 我需要执行异步回调,经过数小时的研究后,我仍然不知道是否应该使用块或GCD和队列。 任何指针都会受到欢迎。

好。 所以我真正要问的是:

“为了使用'异步'回调,我是否需要使用GCD和队列?”

我从答案中收集的是答案是肯定的 。 绝对是GCD内的队列

我的困惑源于这样一个事实,即我得到的方向是我所需要的只是一个块,如下面的代码所示:

[UIView animateWithDuration:.4f
                 animations:^{
                     flashView.alpha = 0.f;
                 }
                 completion:^(BOOL finished){
                     [flashView removeFromSuperview];
                 }
 ];

但我在答案中看到的是上面的块不足以进行“异步”回调。 相反,我实际上需要在内使用GCD队列 ,如下面的代码:

- (void)invokeAsync:(id (^)(void))asyncBlock resultBlock:(void (^)(id))resultBlock errorBlock:(void (^)(id))errorBlock {
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        id result = nil;
        id error = nil;
        @try {
            result = asyncBlock();
        } @catch (NSException *exception) {
            NSLog(@"caught exception: %@", exception);
            error = exception;
        }
        // tell the main thread
        dispatch_async(dispatch_get_main_queue(), ^{
            NSAutoreleasePool *secondaryPool = [[NSAutoreleasePool alloc] init];
            if (error != nil) {
                errorBlock(error);
            } else {
                resultBlock(result);
            }
            [secondaryPool release];
        });
        [pool release];
    });
}

I am new to asynchronous callbacks and have been given differing advice. I need to perform asynchronous callbacks and after many hours of research I still do not know if I should use blocks or GCD and queues. Any pointers would be welcome.

OK. So what I was really asking is:

"in order to use an 'asynchronous' callbacks, do I need to use GCD and queues?"

What I am gathering from the answers is that the answer is YES. Definitely GCD and queues inside of blocks.

My confusion stemmed from the fact that I had been given the direction that all I needed was a block, like the code below:

[UIView animateWithDuration:.4f
                 animations:^{
                     flashView.alpha = 0.f;
                 }
                 completion:^(BOOL finished){
                     [flashView removeFromSuperview];
                 }
 ];

But what I am seeing in the answers here is that the above block in not sufficient for making 'asynchronous' callbacks. Instead I DO in-fact need to use GCD and queues inside a block, like the code below:

- (void)invokeAsync:(id (^)(void))asyncBlock resultBlock:(void (^)(id))resultBlock errorBlock:(void (^)(id))errorBlock {
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        id result = nil;
        id error = nil;
        @try {
            result = asyncBlock();
        } @catch (NSException *exception) {
            NSLog(@"caught exception: %@", exception);
            error = exception;
        }
        // tell the main thread
        dispatch_async(dispatch_get_main_queue(), ^{
            NSAutoreleasePool *secondaryPool = [[NSAutoreleasePool alloc] init];
            if (error != nil) {
                errorBlock(error);
            } else {
                resultBlock(result);
            }
            [secondaryPool release];
        });
        [pool release];
    });
}

原文:https://stackoverflow.com/questions/19310522
更新时间:2022-11-07 17:11

最满意答案

我会选择:

  • 在左侧创建包含较小列表空间的页面,在右侧创建人员列表。

使用以下内容在表格中显示带分页的人:

<table id="people">
    <tr>
        <td id="<?php echo $person['id']; ?>"><?php echo $person['name']; ?></td>
    </tr>
</table>

当有人点击tr时,javascript代码被执行以发送带有id的人的帖子请求。 负责处理的PHP文件将id存储在$_SESSION['selectedPeople']数组中,如果存在则将其从那里删除。 此外,当您单击td时,将切换.selected类,并更新左侧所选人员列表(例如,通过从PHP文件获取JSON并将其处理以显示在表中)。

  • 你可以随时按提交。 它会:

a)带你到另一页并提交列表(你有$_SESSION['selectedPeople']变量)b)发送一个ajax调用页面,它将处理$_SESSION['selectedPeople']

一些代码:

selectHandler.php:

<?php
if($_POST && isset($_POST['id'])) {
    $id = (int)$_POST['id'];
    $action = '';
    session_start();
    if(!isset($_SESSION['selectedPeople'])) {
        $_SESSION['selectedPeople'] = array($id);
        $action = 'added';
    } else {
        if(in_array($id, $_SESSION['selectedPeople'])) {
            $_SESSION['selectedPeople'] = array_diff($my_array, array($id));
            $action = 'removed';
        } else {
            $_SESSION['selectedPeople'][] = $id;
            $action = 'added';
        }
    }
    echo json_encode(array('action' => $action));
}
?>

Javascript(+ JQuery ):

$(function () {
    $('#people tr').click(function () {
        var id = $(this).children('td[id]').attr('id');
        $.post("selectHandler.php", { id: id })
            .done(function( data ) {
                if(data.action == "added") {
                    $(this).addClass('selected');
                } else if(data.action == "removed") {
                    $(this).removeClass('selected');
                } else {
                    alert('Some kind of error.');
                }
            }, "json");
        refreshSelectedList();
    });
});

我希望你明白这个主意。


I would go with:

  • Create page with space for smaller list on the left and list of people on the right.

Display people, with pagination, in table using something like this:

<table id="people">
    <tr>
        <td id="<?php echo $person['id']; ?>"><?php echo $person['name']; ?></td>
    </tr>
</table>

When someone clicks on tr javascript code is executed to send post request with id the person. PHP file responsible for handling this stores the id in the $_SESSION['selectedPeople'] array or removes it from there if it is present. Also, when you click on td, .selected class is toggled and list of selected people on the left side is updated(for example, via getting JSON from PHP file and processing it to display in the table).

  • you can press submit at any time. It would:

a) take you to the other page and submit the list(you have $_SESSION['selectedPeople'] variable) b) send an ajax call to page which will process $_SESSION['selectedPeople']

Some code:

selectHandler.php:

<?php
if($_POST && isset($_POST['id'])) {
    $id = (int)$_POST['id'];
    $action = '';
    session_start();
    if(!isset($_SESSION['selectedPeople'])) {
        $_SESSION['selectedPeople'] = array($id);
        $action = 'added';
    } else {
        if(in_array($id, $_SESSION['selectedPeople'])) {
            $_SESSION['selectedPeople'] = array_diff($my_array, array($id));
            $action = 'removed';
        } else {
            $_SESSION['selectedPeople'][] = $id;
            $action = 'added';
        }
    }
    echo json_encode(array('action' => $action));
}
?>

Javascript(+JQuery):

$(function () {
    $('#people tr').click(function () {
        var id = $(this).children('td[id]').attr('id');
        $.post("selectHandler.php", { id: id })
            .done(function( data ) {
                if(data.action == "added") {
                    $(this).addClass('selected');
                } else if(data.action == "removed") {
                    $(this).removeClass('selected');
                } else {
                    alert('Some kind of error.');
                }
            }, "json");
        refreshSelectedList();
    });
});

I hope you get the idea.

相关问答

更多
  • 我不确定我是否正确,但可能这就是你想要的: var resources = new List(); foreach (DictionaryEntry entry in resourceSet) { resources.Add(entry.Key.ToString()); } UPDATE 好的,那么这是另一个解决方案。 您可以遍历resourceSet的值,如果任何值是Bitmap ,则将其转换为BitmapImage并添加到列表中。 像这样: var images = resou ...
  • 尝试这个: public Object[] toArray() { int size = 1; Node curr = head; while (curr.getNext() != null) { size++; curr = curr.getNext(); } Object[] arr = new Object[size]; //arr[0] = head; ...
  • 尝试这个: include 'phpQuery.php'; $string = '
    1. Coffee
    2. Tea
    3. Milk
    '; $content = phpQuery::newDocument($string)->find('ol li'); $drinks = array(); foreach ($content as $li) { $drinks[] = pq($li)->text(); } print_r($drink ...
  • 您需要将项添加到multiselect的数据源。 $('#items').data("kendoMultiSelect").dataSource.add( { ID: 1, Name: "Name" }); 这是一个现场演示: http : //jsbin.com/eseYidIt/1/edit You need to add items to the data source of the multiselect. $('#items').data("kendoMultiSelect").dataSour ...
  • 我会选择: 在左侧创建包含较小列表空间的页面,在右侧创建人员列表。 使用以下内容在表格中显示带分页的人:
    当有人点击tr时,javascript代码被执行以发送带有id的人的帖子请求。 负责处理的PHP文件将id存储在$_SESSION['selec ...
  • 你必须写下如下代码: