gpt4 book ai didi

objective-c - 为什么 dispatch_async(dispatch_get_main_queue()) 之后的 block 永远不会被调用?

转载 作者:行者123 更新时间:2023-12-04 03:03:51 24 4
gpt4 key购买 nike

我想异步执行一些代码,因此开始使用 GCD for OSX/iOS。
目前我正在使用函数 dispatch_async()
当我想在另一个线程上同时执行某些操作时,我使用函数 dispatch_get_global_queue()
当我想将结果分派(dispatch)到主线程时,我使用函数 dispatch_get_main_queue()
但是结果永远不会到达主线程。

在调试器中设置断点时(在 dispatch_async 行),函数 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 之后的 block 只是有时会被执行,但调试器通常会忽略它。
当 block 确实被执行并且执行流到达断点处的 dispatch_async(dispatch_get_main_queue() 时,之后的 block 总是被忽略。

如果没有 dispatch_async(dispatch_get_global_queue)dispatch_async(dispatch_get_main_queue),代码会按预期执行,尽管是同步执行。

我的问题是为什么 dispatch_async(dispatch_get_main_queue() block 内的 dispatch_async(dispatch_get_global_queue() 永远不会执行?
同样,为什么 dispatch_async(dispatch_get_global_queue() block 不是每次都执行?

我的开发环境是
操作系统:OS X 10.11.3
IDE:Xcode 7.2
编译器:Apple LLVM 版本 7.0.2 (clang-700.1.81)
目标:x86_64-apple-darwin15.3.0

这是一个重现不稳定行为的简单示例(OS X 控制台应用程序):

TestClass.h

#ifndef TestClass_h
#define TestClass_h

@interface TestClass : NSObject {
}

- (void)testMethod:(NSString *)testString withCompletionBlock:(void(^)(NSString *blockResult, NSError __autoreleasing *error))completionBlock;

@end

#endif

TestClass.m

#import <Foundation/Foundation.h>
#import "TestClass.h"

@implementation TestClass

- (void)testMethod:(NSString *)testString withCompletionBlock:(void(^)(NSString *blockResult, NSError __autoreleasing *error))completionBlock {
__block NSString *stringResult = nil;

if (completionBlock) {
__block NSError *resultError = nil;


dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// THIS BLOCK IS CALLED ONLY SOMETIMES, MOST OF THE TIME IT IS IGNORED.

if ([testString isEqual: @"Error string"]) {
NSDictionary *errorUserInfo = @{ NSLocalizedDescriptionKey: @"This is an error.", NSLocalizedFailureReasonErrorKey: @"", NSLocalizedRecoverySuggestionErrorKey: @"" };
resultError = [[NSError alloc] initWithDomain:@"com.test.TestErrorDomain" code:10 userInfo:errorUserInfo];
}
else {
stringResult = testString;
}

dispatch_async(dispatch_get_main_queue(), ^{
// THIS BLOCK NEVER GETS EXECUTED.

completionBlock(stringResult, resultError);
});
});
}
}

@end

main.m

#import <Foundation/Foundation.h>
#import "TestClass.h"

int main(int argc, const char * argv[]) {
@autoreleasepool {
__block NSString *resultString = nil;
TestClass * testObject = [[TestClass alloc] init];

// Output for this call should be: The result string is: Test string.
[testObject testMethod:@"Test string" withCompletionBlock:^(NSString *blockString, NSError __autoreleasing *error) {
resultString = blockString;

if (resultString) {
NSLog(@"The result string is: %@.", resultString);
}
}];

// Output for this call should be: Error: This is an error.
[testObject testMethod:@"Error string" withCompletionBlock:^(NSString *blockString, NSError __autoreleasing *error) {
resultString = blockString;

if (!resultString) {
if (error) {
NSLog(@"Error: %@", [error localizedDescription]);
}
else {
NSLog(@"Error not recognized!");
}
}
}];
}

return 0;
}

最佳答案

那是因为一旦 main() 函数退出,您的 TestClass 对象就会被释放。由于主要是异步的,testMethod: 不会阻塞 main() 中的指针。

尝试在 main() 的末尾添加一个信号量。此信号量应在 testMethod dispatch_async(dispatch_get_main_queue(), ^{}); block 中发出信号。

关于objective-c - 为什么 dispatch_async(dispatch_get_main_queue()) 之后的 block 永远不会被调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35066156/

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