大中央调度块线程安全吗?
Are grand central dispatch blocks thread safe?
我有一个名为TestView的类,它有一个名为'loader'的实例变量,类型为loader。我在TestView上创建了一个方法来实例化加载器;然后在2秒后开始加载。
这个方法是这样的:
-(void) createLoaderAndStartLoadingTwoSecondsLater{
loader = Loader();
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
printf("DISPATCHING AFTER %i seconds", i);
loader->load(*urlRequest);
});
}
在其他地方,有一个dealloc方法:
-(void) dealloc
{
delete loader;
}
在2秒计时器结束之前调用dealloc是可能的。在这种情况下,我希望dispatch_after块永远不会执行。
编辑:我想这样做:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
printf("DISPATCHING AFTER %i seconds", i);
if ( !hasBeenDeleted( loader ) ){
loader->load(*urlRequest);
}
});
但我担心两件事:
- 我不知道如何实现一个已被删除的函数
- 我担心hasBeenDeleted会返回false,然后加载器会在另一个线程上被删除。
所以我真的想这样做:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
printf("DISPATCHING AFTER %i seconds", i);
lockTheOtherThreads();
if ( !hasBeenDeleted( loader ) ){
loader->load(*urlRequest);
}
unlockTheOtherThreads();
});
但我也不知道如何实现lockTheOtherThreads()
假设你有这个
@implementation MyClass {
Loader *loader;
}
-(void)createLoaderAndStartLoadingTwoSecondsLater{
loader = new Loader();
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
printf("DISPATCHING AFTER %i seconds", i);
loader->load(*urlRequest);
//self->loader->load(*self->urlRequest);
});
}
您创建的调度块将保留对self
的强引用,这意味着dealloc
在块执行之前不会被调用。
也使用unique_ptr
,所以你不需要调用delete。或者shared_ptr
+ atomic_load
,如果加载器可以被多个线程访问。
@implementation MyClass {
std::unique_ptr<Loader> loader;
}
-(void)createLoaderAndStartLoadingTwoSecondsLater{
loader.reset(new Loader()); // will delete previous loader if it exist
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
printf("DISPATCHING AFTER %i seconds", i);
loader->load(*urlRequest);
});
}
// you don't need dealloc anymore
更新:
您可以捕获块中对self
的弱引用,以避免它延长self
的生存期
-(void)createLoaderAndStartLoadingTwoSecondsLater{
loader.reset(new Loader()); // will delete previous loader if it exist
__weak typeof(self) weakSelf = self; // a weak reference to self
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
typeof(weakSelf) strongSelf = weakSelf;
printf("DISPATCHING AFTER %i seconds", i);
if (strongSelf) { // if still alive
strongSelf->loader->load(*urlRequest);
} // else it is deallocated
});
}
您实际上想要做什么并不清楚。事情不仅仅是"线程安全",你还需要说明你想做什么。
一旦dealloc被调用,当dealloc返回时,该对象将消失。就算别人想要保留也没关系。看来你把Objective-C和c++搞混了。在c++中调用delete时,对象就消失了。
我建议你仔细阅读Objective-C中的弱指针,远离c++。
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 如何将元素添加到数组的线程安全函数?
- C++中的线程安全删除
- 在std::thread中,joinable()然后join()线程安全吗
- 在c++队列中使用pop和visit实现线程安全
- 以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
- 全局变量 多读取器 一个写入器多线程安全?
- 共享队列的线程安全
- boost::文件系统::recursive_directory_iterator多线程安全
- 静态 constexpr 类成员变量对多线程读取是否安全?
- 以线程安全的方式转换 C/C++ 中时区名称字符串的时区偏移量
- 线程安全运算符<<
- 如何使缓存线程安全
- C++线程安全:如果只有一个线程可以写入非原子变量,但多个线程从中读取. 会遇到问题吗?
- 提升精神 V2 Qi 语法线程安全吗?
- 线程调用的函数对对象删除是否安全?
- asio 链对象线程安全吗?
- 线程安全队列 c++
- 提供对不同类型的数据(建议、代码审查)的线程安全访问的类
- 有没有更好的方法可以使此代码线程安全?线程局部静态似乎是一个生硬的工具