【问题标题】:Synchronized access to UITableViewDelegate logic同步访问 UITableViewDelegate 逻辑
【发布时间】:2026-02-20 17:00:02
【问题描述】:

我想问一个关于表格视图和@synchronized 构造的问题。 我必须执行一次didSelectRowAtIndexPath 中的代码,即使用户不断点击表格单元格...

我有一张桌子用作游戏中的菜单。我想提供对didSelectRowAtIndexPath 中实现的逻辑的同步访问。

我写了以下代码:

//condition = YES in init code

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        @synchronized( self)
        {
            if( !condition)
            {
                NSLog(@"multiple execution is not allowed...");
                return;
            }
            condition = NO;
            ...
            //code
            ...
        }
    }

我在我的 ipone 3gs 上使用 ios 4.3.4 对其进行了测试并且工作(我进行了测试并且行为符合预期)但我的客户在安装了 ios 3.x 的 3g 上对其进行了测试,它似乎不起作用。

我考虑过使用 GCD(通过在 dispatch_once() 中包含代码),但从 ios 4.x 开始支持它。

您知道为什么@synchronized 在我客户的手机上不起作用吗?

谢谢!

【问题讨论】:

    标签: iphone ios synchronized didselectrowatindexpath uitableview


    【解决方案1】:

    @synchronized 这里应该不需要。

    • 您可以期望从主线程进行委托调用(假设您不调用它)。
    • dispatch_once 在这里似乎是一个不寻常的选择。如果您确定它很好,请尝试使用 iOS 3 的pthread_once。这很奇怪,因为它使用可变的全局状态运行。 IOW,“我只想做一张桌子”。
    • 测试 BOOL 很快。

    我的猜测?您的表正在被删除(视图卸载)并且可能无法在重新加载时重新创建。

    【讨论】:

    • 感谢您的回答。我想过使用 dispatch_once 来找到一种方法来执行与点击表行相关的代码。我通过在 didSelectRowAtIndexPath 实现中设置断点来验证问题,当在断点处停止时,我点击了另一个时间,另一个线程进入了 didSelectRowAtIndexPath,所以我发现自己处于竞争状态..
    • hmmm...如果您确定仅从主线程调用它,不知道该说什么。您是否偶然禁用 objc 或c++ 异常?如果是这样,请在启用它们的情况下尝试。通常,我只是将逻辑拉到一个单独的方法中。否则,程序的其他部分可能不是线程安全的,或者您可能正在以非常规的方式初始化和销毁​​。