What's the right way to set an NSError outparam from inside an autoreleasepool block?

拟墨画扇 提交于 2019-12-10 02:32:06

问题


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.
    }
}

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.

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

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.

Any thoughts? Thanks.


回答1:


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).



来源:https://stackoverflow.com/questions/14489969/whats-the-right-way-to-set-an-nserror-outparam-from-inside-an-autoreleasepool-b

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!