【问题标题】:wrap & unwrap with NSValue使用 NSValue 进行包装和解包
【发布时间】:2016-08-12 20:48:47
【问题描述】:

在我的项目中,我有这样的功能:

- (void)doSomething:(NSError**)error {
...
}

我需要使用函数 performSelector:onThread:withObject:waitUntilDone: 在另一个线程上调用此函数,如下所示:

[self performSelector:@selector(doSomething:) onThread:anotherThread withObject:??? waitUntilDone:NO];

但是函数参数的类型是NSError**。我正在考虑将函数-(void)doSomething: 的参数类型从NSError** 重构为NSValue*,并将NSValue* 类型作为参数传递。

这意味着,我需要将&error(类型为NSError **)包装成NSValue,并将其作为参数传递,然后再将其解包。如何用NSValue类包装和解包NSError**

【问题讨论】:

  • 为什么需要将NSError 包裹在NSValue 中?
  • 我想包装 NSError** 并将包装后的 NSValue 作为 argment 传递,然后调用 performSelector:withObject ,
  • 1) 为什么你需要用NSValue 包裹NSError 只是为了将它传递给performSelector:withObject:?没必要把它包起来。 2) 为什么需要使用performSelector:withObject:?总有比这更好的方法。我建议更新您的问题,详细说明您真正需要完成的工作,以便人们提供更好的建议。
  • 我将更详细地更新我的问题,谢谢。
  • 更新了更多细节

标签: ios objective-c nserror nsvalue


【解决方案1】:

我认为你可以使用NSValuevalueWithPointer:pointerValue。但我建议你使用其他东西,比如 GCD 来异步运行一个块,而不是更改方法的签名以适应 performSelector 的限制:

dispatch_async(anotherQueue, ^{
    [self doSomething:&error];
});

如果你真的想走这条路,this question 也有更多关于如何解决这个问题的想法。

【讨论】:

  • 谢谢,但我需要使用otherThread 变量,所以我需要使用 performSelector:onThread:WithObject
【解决方案2】:

您需要重新考虑解决此问题的方法。你的方法:

- (void)doSomething:(NSError**)error

遵循传递NSError * 变量的地址 的标准Objective-C 模式,以便方法可以设置变量以返回错误。

如果您尝试异步调用此方法,无论是尝试使用 performSelector:onThread:withObject:waitUntilDone: 还是使用 GCD(正如 Felipe Cypriano 也建议的那样),您必须小心 - 您传递其地址的变量必须作为时间存在异步调用被执行,即使你已经解决了你必须弄清楚异步调用何时完成,这样你才能检查它是否设置了变量......

处理此类问题的常用方法是使用完成块,异步方法在完成时调用该完成块,传递任何结果 - 在您的情况下为 NSError *。例如你可以写一个方法:

- (void) doSomethingAsyncAndThen:(void (^)(NSError *))completionBlock
{
   dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0),
                  ^{
                     NSError *error = nil;
                     [self doSomething:&error];
                     completionBlock(error);
                  });
}

然后这样称呼它:

[self doSomethingAsyncAndThen:^(NSError *error) { NSLog(@"error: %@", error); }];

虽然你会想要做的不仅仅是NSLog 结果。

HTH

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    • 2013-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-03
    • 2016-06-14
    相关资源
    最近更新 更多