首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用NSValue包装和展开

使用NSValue包装和展开
EN

Stack Overflow用户
提问于 2016-08-13 04:48:48
回答 2查看 125关注 0票数 0

在我的项目中,我有一个这样的函数:

代码语言:javascript
复制
- (void)doSomething:(NSError**)error {
...
}

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

代码语言:javascript
复制
[self performSelector:@selector(doSomething:) onThread:anotherThread withObject:??? waitUntilDone:NO];

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

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

EN

回答 2

Stack Overflow用户

发布于 2016-08-13 05:34:53

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

代码语言:javascript
复制
dispatch_async(anotherQueue, ^{
    [self doSomething:&error];
});

此外,如果你真的想走这条路,this question还有一些关于如何解决这个问题的想法。

票数 0
EN

Stack Overflow用户

发布于 2016-08-13 07:20:06

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

代码语言:javascript
复制
- (void)doSomething:(NSError**)error

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

如果您尝试异步调用此方法,无论是尝试使用performSelector:onThread:withObject:waitUntilDone:还是使用GCD ( Felipe Cypriano也建议),您都必须小心--在执行异步调用时,您传递的变量的地址必须存在,即使您已经解决了异步调用何时结束的问题,以便您可以检查它是否设置了变量……

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

代码语言:javascript
复制
- (void) doSomethingAsyncAndThen:(void (^)(NSError *))completionBlock
{
   dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0),
                  ^{
                     NSError *error = nil;
                     [self doSomething:&error];
                     completionBlock(error);
                  });
}

然后这样叫它:

代码语言:javascript
复制
[self doSomethingAsyncAndThen:^(NSError *error) { NSLog(@"error: %@", error); }];

尽管你想要做的不只是NSLog结果。

HTH

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38926249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档