- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我是 Objective-C 的新手。如果我有一个类属性可能会在 API 调用等异步事件期间被修改,那么确保在其他人访问属性时更改属性的最佳方法是什么线程不会导致崩溃?
据我所知,我有两个选择:
1) NSLock + 原子属性
...但在这种情况下,我似乎必须为每次读写锁定属性,这对我来说会破坏将其设置为原子的目的。
2) 非原子性质
我也可以将它设置为非原子的,但我想我必须在主线程上进行所有读/写。有没有办法通过 API 调用来做到这一点?成功的 API 响应后对委托(delegate)的回调是在为该 API 调用打开的线程上,还是在主线程上?如果它在不同的线程上,我可以把它放回主线程吗?具体来说,我担心 NSArray 在另一个线程循环通过它时发生变化。
这样做的最佳方法是什么?
最佳答案
我想拿贾斯汀的选项“dispatch APIs”作为一个简短的例子:
通过在专用串行队列上执行所有访问,可以使对共享资源的并发访问变得安全,我们称之为“sync_queue”。
这个“sync_queue”可能是类的私有(private)队列,其 ivars 是您要修改的资源。
您现在可以定义一个读/写非原子属性,例如:
@propery (nonatomic) NSArray* array;
写入 访问可以如下所示实现:
- (void) setArray:(NSArray* newValue)
{
dispatch_async(sync_queue, ^{
_array = newValue;
});
}
请注意,写访问是异步的。
对该属性的读取 访问将按如下方式实现:
- (NSArray*) array:(NSArray* value)
{
if (dispatch_get_specific(SyncQueueID) == sync_queue_id)) {
return _array;
}
else {
__block NSArray* result = nil;
dispatch_sync(_sync_queue, ^{
result = _array;
});
return result;
}
}
与写入访问不同,读取访问需要同步。该方法还必须检查当前执行上下文是否已经是 sync_queue 或同步队列的子级或任何孙子级 - 否则,读取访问将导致死锁。
为了识别当前执行上下文,我们使用函数 dispatch_queue_set_specific() 将特定标识符与同步队列关联起来。创建它时。稍后我们使用 dispatch_get_specific从当前队列或从父队列或任何祖父队列获取此标识符。如果它返回这个特定的标识符,则该方法分别在子队列或任何孙子队列的同步队列上执行。如果是,该方法会立即返回值。否则,它会在同步队列上进行同步调度。
如果共享资源将被 UIKit 访问,则 sync_queue 应为主队列。
关于objective-c - NSLock + 原子属性 vs 非原子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17518846/
我需要在发出异步请求之前设置一个互斥锁,然后在另一个线程上的这个请求的回调中解锁互斥锁。 苹果文档说: Warning: The NSLock class uses POSIX threads to
我有一个以 a 开头的循环 [lock lock]; 因为在循环体中我正在创建另一个线程,该线程需要在循环再次运行之前完成。 (完成后另一个线程将解锁它)。 但是在第二个循环中我收到以下错误: 201
我有一个属性@property NSLock *myLock 我想写两个方法: - (void) lock 和 - (void) unlock 这些方法分别锁定和解锁myLock并且无论调用它们的线程
我有一个全局变量,可以从多个线程访问,包括从主线程访问。我想使用 NSLock because it’s faster than GCD . 这是我正在尝试做的事情: struct Synchroni
使用 NSLock 在我们的日志中看到这条消息: *** -[NSLock lock]: deadlock ( '(null)') *** Break on _NSLockError() to deb
我正在审查一些 Alamofire sample重试代码: func should(_ manager: SessionManager, retry request: Request, with
我目前有一组异步函数,它们都在 viewDidLoad() 中调用。每个函数的末尾都有一个 bool 值,在函数完成时将其从 false 设置为 true。还有一个条件语句检查触发第三个函数的两个函数
我正在处理多线程代码。数据访问通过“NSLock”对象锁定在多个部分。我想确保在这些部分中调用的某些方法会检查是否获得了适当的锁。 类似于: assert([myLock isSet] == YES)
我应该做一个NSLock应用程序委托(delegate)中的实例,供所有类使用?还是建议让每个类实例化自己的NSLock根据需要实例? 例如,如果我可以访问分布在两个 View Controller
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 2 年前。 Improv
在这种情况下,我必须等待 UIKit 动画完成,并且我正在使用完成 block 来执行相关的最终代码。现在我已经意识到,当我从主线程调用该函数两次时,我可以触发一个引入错误的竞争条件。我无法使用简单的
我正在编写代码来渲染和旋转一张图片,其细节正在同时计算和更新。它在单个线程(带有显示链接)上无错误地工作,但看起来很笨重,而且我不希望显示链接触发计算。所以我想在主线程(带有显示链接)中执行所有与 O
我遇到了线程安全问题。我有一个队列,当我修改内容时导致跨线程错误。我以前没用过锁,但我想试试。我在为我的队列操作支持 NSMutableArray 的所有代码周围添加了一个锁。我认为,问题是我没有对所
我有一段代码经常被主线程或其他几个后台线程访问。我需要确保一次只处理一个代码。 我目前正在使用 @synchronized(self) { } block ,但我不确定它是否提供了正确的保护。它与 N
我一直在使用 NSLock 来同步敏感的代码部分,但一直遇到问题,因为它们必须从锁定它们的同一线程解锁。然后我发现 GCD 的 DispatchSemaphore 似乎在做同样的事情,而且更方便的是它
从编程的角度来看,由于代码的编写方式,我不一定能解决这个问题。 基本上,用伪代码表示: if NSUserDefaults' stored token exists{ setFlag(toke
谁能简要说明这 3 个系统在线程安全方面的优缺点? 通过观看最近的 WWDC 视频,我感觉到 Apple 正在插入 GCD 的使用,以创建线程安全的高性能读写器。 这背后的想法/支持是什么?是时候访问
我阅读了有关 GCD 队列的 Apple 文档,开始想知道如果我让修改类型为 NSMutableArray 的实例成员在串行队列中不是线程安全的,会发生什么情况?串行队列会保证我串行执行操作,但我仍然
我是 Objective-C 的新手。如果我有一个类属性可能会在 API 调用等异步事件期间被修改,那么确保在其他人访问属性时更改属性的最佳方法是什么线程不会导致崩溃? 据我所知,我有两个选择: 1)
我有一些 Objective-C 代码,它使用 NSLock 来实现某种事务。该对象在“开始事务”上被锁定,在锁定到位的情况下进行了几次其他调用,然后通过“提交”将其释放。我正在编写一个 JNI 粘合
我是一名优秀的程序员,十分优秀!