我目前正在使用iPhone应用程序,并且我有一个第三方库,该库具有异步行为,但我想包装自己的类并使其显示为同步。

该库中的中心类(我们称为Connection类)具有多个函数,这些函数在调用委托(delegate)类的实例上的方法时会解决最终结果。我想做的是包装此类和委托(delegate),以便它看起来是同步的而不是异步的。如果我在Java中执行此操作,则将使用FutureTask或CountdownLatch或仅使用join()。但是我不确定在 objective-c 中执行此操作的最佳方法。

我首先创建一个符合上述委托(delegate)协议(protocol)的NSThread扩展NFCThread。我的想法是,我将初始化和NFCThread,将NFCThread实例传递给Connection的setDelegate方法,启动线程,然后在Connection上调用异步方法。我的期望是,将调用NFCThread实例上的三个委托(delegate)方法之一,最终导致线程退出。

为了模拟联接,我执行了以下操作。我在NFCThread中添加了NSConditionalLock:

joinLock = [[NSConditionLock alloc] initWithCondition:NO];

调用Connection的代码如下所示:
NFCThread *t = [[NFCThread alloc] init];
[connection setDelegate:t];
[t start];

[connection openSession];
// Process errors, etc...

[t.joinLock lockWhenCondition:YES];
[t.joinLock unlock];
[t release];
[connection setDelegate:nil];

代表的协议(protocol)有三种方法。在NFCThread中,我实现了每个方法,如下所示:
- (void)didReceiveMessage:(CommandType)cmdType
                     data:(NSString *)responseData
               length:(NSInteger)length {
    NSLog(@"didReceiveMessage");
    // Do something with data and cmdType...
    [joinLock lock];
    [joinLock unlockWithCondition:YES];
    callBackInvoked = YES;
}

我重载了NFCThread的main方法,以便它不断循环。像这样的东西:
while (!callBackInvoked) { ; }

我发现这并不是一个好主意,因为它会导致CPU使用率不断上升。因此,我尝试使用在此站点上找到的一些示例中的运行循环:
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];

while (!callBackInvoked) {
    [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}

在我的两个实现中,主线程始终处于阻塞状态,并且似乎从未调用过任何委托(delegate)方法。但是,我知道该库运行正常,并且通常会调用对委托(delegate)方法的调用。

我觉得这里缺少明显的东西。任何帮助,不胜感激。

富有的

最佳答案

好的,所以这里有一些不同的问题,我正在尝试着从哪里开始。

但是,只有这样,我们了解您要完成的工作,当您说要使调用“出现”同步时,是否意味着要阻止该调用?您是从主线程发出此调用吗?如果是这样,那么看来您是在设计中阻塞了主线程。

请记住,第三方库可能正在主运行循环上安排事件。您可以创建自己的运行循环并在另一个线程中运行,但是您是否已告诉另一个库对该事件使用该运行循环? (例如,它可能正在根据已阻止的主运行循环发出异步网络请求)

我会重新考虑您在做什么,但是首先我们需要知道您的意图是否是阻塞从中进行此调用的线程。另外,您需要支持iPhoneOS 3.x吗?

09-12 09:24