gpt4 book ai didi

ios - Objective-C 中的 @syncronized block 是否保证在上下文切换到执行其他代码之前完全执行该 block ?

转载 作者:行者123 更新时间:2023-11-28 23:30:58 24 4
gpt4 key购买 nike

我有一个 UITableView 的数据源。有时我在 cellForRowAt 方法中得到一个 indexOutOfBound 异常,因为它可能发生在 tableView 的 numberOfRowsInSection 方法被调用然后上下文切换并且由于某种原因数据源中的项目需要更新(删除特定项目并添加这些项目的更新版本)但是当它只是删除项目并且在添加新项目之前上下文被切换回并尝试加载单元格但随后一些项目被删除所以它抛出异常。

我想在一个 block 中进行绑定(bind)删除和添加,这样它只会在执行完整 block 后更改上下文,即

[self removeObjects:@[ lastUserChatMessage ]];
lastUserChatMessage.state = KUSChatMessageStateFailed;
[ self upsertObjects:@[ lastUserChatMessage ]];

我希望上下文在第一个语句之后永远不会切换。它必须执行到最后一条语句。

@syncronized block 可以达到这个目的吗?但请记住,所有操作都在主线程中完成。

最佳答案

我认为这对你的情况没有多大意义。 TableView 可以选择在任何给定时间调用任何数据源方法。您需要保管好您的数据以使其保持一致。通常,当您更改数据源时,您应该调用 reloadData 或在 TableView 上执行开始/结束更新过程。由于 TableView 在主线程上工作,因此在处理数据时应该执行相同的操作。

因此,如果您正在处理多个线程或无论如何无法控制地修改数据源,那么您应该在完成后始终创建一个副本。然后使用该副本作为数据源并重新加载 TableView 。在最坏的情况下,你应该这样做:

- (void)setNewData:(NSArray *)newData {
NSArray *duplicate = [newData copy];
dispatch_async(dispatch_get_main_queue(), ^(void){
self.dataArray = duplicate;
[self.tableView reloadData];
});
}

在这种情况下,self.dataArray 应该在 TableView 数据源方法中使用,它永远不会让您失望。

关于ios - Objective-C 中的 @syncronized block 是否保证在上下文切换到执行其他代码之前完全执行该 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56539502/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com