简体   繁体   English

iOS:dispatch_block_t执行两次代码的一部分,我不知道为什么

[英]iOS: dispatch_block_t execute some part of code two times and I dont know why

When I call the following function: 当我调用以下函数时:

+ (void) myMethod:(NSString *) myConstString array: (NSArray *) myArray
{
    dispatch_block_t block = 
    ^{
        for (int i = 0; i < myArray.count; i++)
        {
            if ([@"myString1"  isEqual: myConstString])
                // Do some easy job here

            else if ([@"myString2"  isEqual: myConstString])
                // Do some other easy job here

            [NSThread sleepForTimeInterval: 0.5];
        }

        [[NSNotificationCenter defaultCenter] postNotificationName:@"test" object:nil userInfo:nil];
    };

    dispatch_queue_t backgroundQueue = dispatch_queue_create("com.example.test", NULL);
    dispatch_async(backgroundQueue, block);
}

[[NSNotificationCenter...] is executed two times. [[NSNotificationCenter...]被执行两次。 I know that because method in other class which is responsible for "catch" this notification is called two times. 我知道,因为负责“捕获”此通知的其他类中的方法被调用了两次。 First call is instant (and this is strange to me). 第一次打电话是即时的(这对我来说很奇怪)。 Second call is after about 2 seconds (this call I like :-) ) I know how to "repair" this: 第二次通话大约在2秒后(我喜欢这个通话:-)),我知道如何“修复”此功能:

+ (void) myMethod:(NSString *) myConstString array: (NSArray *) myArray {
    dispatch_block_t block = 
    ^{
        Boolean isForLoopExecuted = false;
        for (int i = 0; i < myArray.count; i++)
        {
            if ([@"myString1"  isEqual: myConstString])
                // Do some easy job here

            else if ([@"myString2"  isEqual: myConstString])
                // Do some other easy job here

            [NSThread sleepForTimeInterval: 0.5];
            isForLoopExecuted = true;
        }
        if (isForLoopExecuted)
            [[NSNotificationCenter defaultCenter] postNotificationName:@"test" object:nil userInfo:nil];
    };

    dispatch_queue_t backgroundQueue = dispatch_queue_create("com.example.test", NULL);
    dispatch_async(backgroundQueue, block); }

After addind isForLoopExecuted everything works propertly. 在addind isForLoopExecuted一切正常。 There is only one call after 2 seconds. 2秒后只有一个电话。 This suggests that for loop is not executed when first call is made. 这表明在第一次调用时不执行for循环。 I am really curious why this is happening. 我真的很好奇为什么会这样。 Thanks for your time! 谢谢你的时间!

First off, creating new background queue every time that function runs is probably not what you want. 首先,每次运行函数时创建新的后台队列可能都不是您想要的。 There are limits how many queues you can have, and this is right way to reach that limit quickly and crash. 可以有多少个队列是有限制的,这是快速达到该限制并崩溃的正确方法。 Use something like this: 使用这样的东西:

dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), block); dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY,0),块);

Secondly, there is nothing wrong with first listing (except that background queue) and it works correctly. 其次,第一个列表没有任何问题(后台队列除外),并且可以正常工作。 Notification will be sent just once. 通知将仅发送一次。

What I would suggest is to put log when you are sending notification to see exactly how many times you are executing that function. 我的建议是在发送通知时放置日志,以确切查看执行该功能的次数。 Probably more than once. 可能不止一次。 Also, time that will be spent in queue depends on parameters you are sending there. 另外,将花费在队列中的时间取决于您在此发送的参数。 If myArray is empty, you get notification almost immediately. 如果myArray为空,则几乎立即收到通知。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM