gpt4 book ai didi

ios - Objective-c 验证当前执行线程,以防万一,在正确的线程中重新执行该方法

转载 作者:行者123 更新时间:2023-11-28 19:53:10 26 4
gpt4 key购买 nike

我正在尝试创建一个方法来检查当前线程是什么,如果它与所需线程不同,则在正确的线程中重新执行(调用者)方法。

我正在使用:

-(void)aMethod:(id)aParam
{
[self executeInRightThread];
...
}

这是当前代码:

-(void)executeInRightThread
{
NSString * rightQueueLabel = [NSString stringWithCString:dispatch_queue_get_label(myQueue) encoding:NSUTF8StringEncoding];
NSString * currentQueueLabel = [NSString stringWithCString:dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) encoding:NSUTF8StringEncoding];
BOOL isInTheRightQueue = [currentQueueLabel isEqualToString:rightQueueLabel];

NSString *sourceString = [[NSThread callStackSymbols] objectAtIndex:1]; // Example: 1 UIKit 0x00540c89 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1163
NSCharacterSet *separatorSet = [NSCharacterSet characterSetWithCharactersInString:@" -[]+?.,"];
NSMutableArray *array = [NSMutableArray arrayWithArray:[sourceString componentsSeparatedByCharactersInSet:separatorSet]];
[array removeObject:@""];

// NSLog(@"Stack = %@", [array objectAtIndex:0]);
// NSLog(@"Framework = %@", [array objectAtIndex:1]);
// NSLog(@"Memory address = %@", [array objectAtIndex:2]);
// NSLog(@"Class caller = %@", [array objectAtIndex:3]);
// NSLog(@"Function caller = %@", [array objectAtIndex:4]);
// NSLog(@"Line caller = %@", [array objectAtIndex:5]);
NSString * callerMethodName = [array objectAtIndex:4];

if ( !isInTheRightQueue )
{
dispatch_async(myQueue, ^{
[self performSelector:NSSelectorFromString(callerMethodName)];
});
}
}

executeInRightThread 方法运行良好,但我不知道如何检索调用方方法参数(示例中的 aParam),我不想将参数传递给 executeInRightThread 方法,主要目的是创建可在任何地方使用的东西,无需使用 block ,也无需传递不同的参数。

最佳答案

使用NSThread currentThread 查询当前线程。但是,您的问题有点困惑,因为您随后指定了变量 isInTheRightQueue

您无法查询当前队列 - dispatch_get_current_queue() 已被弃用,并且不会总是返回您期望的内容(并且 dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) 具有完全相同的问题) .我们在 iOS 8 上遇到了一个案例,其中 AVCaptureVideoOutput 配置为在主队列上回调我们。在回调中,我们发现dispatch_get_current_queue()的返回结果不是我们预期的(我们本来调用了setSampleBufferDelegate:... queue:dispatch_get_main_queue(),但是而是:

(lldb) po dispatch_get_current_queue()
<OS_dispatch_queue: com.apple.avfoundation.videodataoutput.bufferqueue[0x170118e40] = { xrefcnt = 0x1, refcnt = 0x3, suspend_cnt = 0x0, locked = 1, target = com.apple.main-thread[0x1001be800], width = 0x0, running = 0x0, barrier = 1 }>
(lldb) p (char*)dispatch_queue_get_label(nil)
(char *) $4 = 0x000000017026f8c0 "com.apple.avfoundation.videodataoutput.bufferqueue"
(lldb) p (char*)dispatch_queue_get_label((dispatch_queue_t)[captureOutput sampleBufferCallbackQueue])
(char *) $6 = 0x00000001001af6b0 "com.apple.main-thread"

请注意,这是一个针对主线程的队列,而不是主队列本身。

队列和线程之间没有映射关系。任何在后台线程上执行的队列——与主线程相反——都可以在任何后台线程上执行。

您想要检查执行线程的正常情况是您是否需要执行影响 UI 的代码。

if(![NSThread isMainThread])
{
dispatch_sync(dispatch_get_main_queue(), ^{ .... });
}

如果您需要验证您是否已在正确的后台队列上被回调,那么您可能需要更清楚地考虑您的应用程序逻辑。但是,如果你真的需要这样做,为什么不对相关的后台队列做一个dispatch_async。这会延迟执行您想要的任务,但由于您已经在后台,这可能无关紧要。

关于ios - Objective-c 验证当前执行线程,以防万一,在正确的线程中重新执行该方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28090795/

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