从autoreleasepool块内部设置NSError outparam的正确方法是什么? [英] What's the right way to set an NSError outparam from inside an autoreleasepool block?

查看:97
本文介绍了从autoreleasepool块内部设置NSError outparam的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个像这样的方法:

I have a method like this:

- (void)processAThing:(id)thing error:(NSError * __autoreleasing *)error
{
    @autoreleasepool {

          // Start processing.

          // Find some partway through error..
          if (error) {
              *error = [NSError errorWithDomain...];
              return NO;
          }

          // More processing.
    }
}

这被破坏并崩溃,因为NSError是自动释放的,并且当返回发生时,池被耗尽,因此调用者得到的东西现在是虚假的.

This is broken and crashes, because the NSError is autoreleased, and when the return happens, the pool is drained, so the thing that the caller gets is now bogus.

我知道我可以极大地重新设计该方法,因此我可以在autorelease块之外收集所有错误情况,但是我想了解在这种情况下是否存在正确的方法来处理错误对象.我不能在池块之​​外分配/初始化一个推测性的NSError,因为域和代码属性是只读的(而且我仍然认为当方法返回时,引用将消失).

I know I could significantly redesign the method so I collect all error cases outside the autorelease block, but I want to understand whether there's a correct way of handling the error object in this situation. I can't alloc/init a speculative NSError outside the pool block, because the domain and code properties are readonly (and I still think the reference would disappear when the method returns).

如果我将方法声明更改为此,它将解决问题:

It solves the problem if I change the method declaration to this:

- (void)processAThing:(id)thing error:(NSError * __strong *)error

但是,然后我需要以一种非标准的方式在呼叫站点上大惊小怪,而让呼叫者为我的内部autoreleasepool付出代价似乎太过分了.

But then I need to fuss around at the call site in a nonstandard way, and this seems egregious to make the caller pay the price for my internal autoreleasepool.

有什么想法吗?谢谢.

推荐答案

我自己遇到了这个问题.在这种情况下,我认为您只需要在@autoreleasepool之前声明一个新的强引用,并在该临时引用的@autoreleasepool块之后设置方法参数即可.

I had this problem myself. In this case, I think you just need to declare a new strong reference just before the @autoreleasepool, and set the method argument just after the @autoreleasepool block from that temporary reference.

- (void)processAThing:(id)thing error:(NSError * __autoreleasing *)error {
  __strong NSError *errOut = nil;
  @autoreleasepool {
    // do your stuff and set errOut instead of error
  }
  if (error) {
    *error = errOut;
  }
}

(在浏览器中键入,未由编译器检查错误)

(typed in browser, not error checked by compiler)

关于您的过早归还,我想您将不得不使用跳转标签(即使它不漂亮).

As for your premature return, I guess you'll have to use a jump label (even if it's not pretty).

这篇关于从autoreleasepool块内部设置NSError outparam的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆