C++ 大中央调度模块是线程安全的吗?
我有一个名为TestView的类,它有一个名为loader的实例变量,类型为loader。我在TestView上创建了一个方法来实例化加载程序;然后在2秒钟后开始加载 该方法如下所示:C++ 大中央调度模块是线程安全的吗?,c++,ios,objective-c,multithreading,grand-central-dispatch,C++,Ios,Objective C,Multithreading,Grand Central Dispatch,我有一个名为TestView的类,它有一个名为loader的实例变量,类型为loader。我在TestView上创建了一个方法来实例化加载程序;然后在2秒钟后开始加载 该方法如下所示: -(void) createLoaderAndStartLoadingTwoSecondsLater{ loader = Loader(); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_g
-(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;
}
dealloc有可能在2秒计时器过去之前被调用。在这种情况下,我希望它如果调度_后块从未执行
编辑:
我想这样做:
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);
}
});
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();
});
但我担心两件事:
- 我不知道如何实现已删除的函数
- 我担心hasbeendelete将返回false,然后加载程序将在另一个线程上被删除李>
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);
}
});
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()不清楚您实际上想做什么。事情不仅仅是“线程安全”,你需要说出你想做什么 调用dealloc后,当dealloc返回时,相关对象将消失。如果有人试图保留它,这并不重要。看起来你正在混合Objtovi-C和C++。当C++中删除时,对象已经消失。
<>我建议你读ObjuleC中的弱指针,远离C++。p> 不清楚你到底想做什么。事情不仅仅是“线程安全”,你需要说出你想做什么 调用dealloc后,当dealloc返回时,相关对象将消失。如果有人试图保留它,这并不重要。看起来你正在混合Objtovi-C和C++。当C++中删除时,对象已经消失。
<>我建议你读ObjuleC中的弱指针,远离C++。p> 不清楚你到底想做什么。事情不仅仅是“线程安全”,你需要说出你想做什么 调用dealloc后,当dealloc返回时,相关对象将消失。如果有人试图保留它,这并不重要。看起来你正在混合Objtovi-C和C++。当C++中删除时,对象已经消失。
<>我建议你读ObjuleC中的弱指针,远离C++。p> 不清楚你到底想做什么。事情不仅仅是“线程安全”,你需要说出你想做什么 调用dealloc后,当dealloc返回时,相关对象将消失。如果有人试图保留它,这并不重要。看起来你正在混合Objtovi-C和C++。当C++中删除时,对象已经消失。
<>我建议你读ObjuleC中的弱指针,远离C++。p> 假设你有这个
@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\u ptr
,这样就不需要调用delete。或者如果多个线程可以访问加载程序,则使用原子加载共享\u ptr
@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
假设你有这个
@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\u ptr
,这样就不需要调用delete。或者如果多个线程可以访问加载程序,则使用原子加载共享\u ptr
@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
假设你有这个
@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\u ptr
,这样就不需要调用delete。或者如果多个线程可以访问加载程序,则使用原子加载共享\u ptr
@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
假设你有这个
@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\u ptr
,这样就不需要调用delete。或者如果多个线程可以访问加载程序,则使用原子加载共享\u ptr
@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
你的最后一段很混乱。“保证执行而不切换线程”是什么意思?无论如何,这与我能想到的任何“线程安全”的定义都不相符。你会怎么检查空值?你认为这将如何让你“处理完毕”?谢谢。当我写它的时候,我没有意识到这是多么的不清楚。我编辑了这个问题,希望能把事情弄清楚。你不应该用一个已经被删除的测试来思考。相反,您应该通过维护强引用来确保它不会被删除。如果你想取消加载,你应该用另一种方式。例如,在已知运行循环(即主运行循环)上使用NSTimer
,并使其无效以取消它。或者,类似地,使用-performSelector:withObject:afterDelay:
,然后使用+cancel先前的performrequestswithtarget:selector:object:
将其取消。在任何情况下,只要延迟的代码挂起,就应该保留加载程序。把它安排好,取消它就是释放它的原因。啊哈,谢谢。实际上,我只想取消异步调度。我不经常使用iOS,而且我忘记了存在performSelector:withObject:afterDelay
和cancelPreviousPerformRequestsWithTarget:selector:object
。这应该可以解决这个问题。你的最后一段很混乱。“保证执行而不切换线程”是什么意思?无论如何,这与我能想到的任何“线程安全”的定义都不相符。你会怎么检查空值?你认为这将如何让你“处理完毕”?谢谢。当我写它的时候,我没有意识到这是多么的不清楚。我编辑了这个问题,希望能把事情弄清楚。你不应该用错误的方式思考