• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

iphone - Objective-C 线程安全计数器

[复制链接]
菜鸟教程小白 发表于 2022-12-13 02:54:04 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我正在尝试以线程安全的方式控制网络事件指示器。

这是我目前正在做的方式,但我认为必须有更好的方式来做到这一点。我一直在寻找使用锁,但这似乎是一项昂贵的操作。我一直在研究 OSAtomicAdd,但不知道在这种情况下如何使用它。

+ (void)start
{
    [self counterChange:1];
}

+ (void)stop
{
    [self counterChange:-1];
}

+ (void)counterChangeNSUInteger)change
{
    static NSUInteger counter = 0;
    static dispatch_queue_t queue;
    if (!queue) {
        queue = dispatch_queue_create("NetworkActivityIndicator Queue", NULL);
    }
    dispatch_sync(queue, ^{
        if (counter + change <= 0) {
            counter = 0;
            [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        } else {
            counter += change;
            [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
        }
    });
}

如何使用 OSAtomicAdd 完成这样的事情?



Best Answer-推荐答案


你不能单独依赖像 OSAtomicAdd 这样的东西来同步这种操作。整个操作需要被锁定以确保它成功运行。

考虑 this answer 中建议的解决方案,这基本上归结为:

static volatile int32_t NumberOfCallsToSetVisible = 0;
int32_t newValue = OSAtomicAdd32((setVisible ? +1 : -1), &NumberOfCallsToSetVisible);
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisiblenewValue > 0)];

如果从一个线程调用此代码,并且将 setVisible 设置为 YES,则对 OSAtomicAdd32 的调用会将 OSAtomicAdd32 加 1 code>NumberOfCallsToSetVisible 导致 newValue 被设置为 1。

现在考虑如果该线程在执行下一行之前被抢占,并且另一个线程调用该函数并将 setVisible 设置为 NO 会发生什么情况。这次对 OSAtomicAdd32 的调用将从 NumberOfCallsToSetVisible 中减去 1,导致 newValue 设置为 0。

如果第二个线程继续执行,并且下一行被执行,newValue 不大于零,所以 setNetworkActivityIndi​​catorVisible 方法将被调用 NO。此时事件指示器仍然不可见,所以这没有任何作用,但也不会造成任何伤害。

但是,最终我们将切换回第一个线程,其中 newValue 设置为 1。所以当该线程执行下一行时,newValue 显然是大于零,setNetworkActivityIndi​​catorVisible 方法将被调用 YES,使事件指示器可见。

所以我们在 setVisible 设置为 YES 的情况下调用了一次函数,并在 setVisible 设置为 NO 的情况下再次调用了该函数。您会期望这会导致事件指示器不可见,但事实并非如此。事实上,如果没有其他调用,它将永远保持可见。这显然是不对的。

最重要的是,您需要将整个东西包装在 @synchronize block 或类似的东西中。

关于iphone - Objective-C 线程安全计数器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17176190/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap