7

There are many Cocoa methods that require an NSError object as a parameter to a method, but are really a means of returning an error object to the calling method if errors exist. Is this returned object retained? That is, in the calling object code (the method to which the error is returned), does there need to be some code like:

  NSError *error;
  [apiCall .... error:&error];

  if (error){
    [*error release];
 }

I haven't seen this anywhere, and if it does need to be released, is this the way to do it?

i_am_jorf
  • 53,608
  • 15
  • 131
  • 222
casademora
  • 67,775
  • 17
  • 69
  • 78

3 Answers3

7

Returned objects are generally autoreleased. The general rule is you only call auto-/release if you earlier called copy/alloc/retain on the same object. And you wouldn't dereference error in a method call:

// right
[error code]
// wrong
[*error code]
outis
  • 75,655
  • 22
  • 151
  • 221
  • The reason I put the [*error code] is that you can also specify the NSError var as: NSError **error; Which is a point to a point to the object. Is this valid? – casademora Oct 29 '09 at 03:28
  • You specify `NSError **` as a type for `error` only when it's an "out parameter" or "output parameter". In that case you would dereference, but note that `*error` would have type `NSError *`. You use out parameters to get around the fact that functions have only one return value. Out parameters in Objc-C use `Type **` because arguments are pass-by-value. Note also that if `error` had type `NSError **`, you'd have to either initialize it with a pointer to an `NSError *` (which is what you do in the API call) or allocate a pointer, which happens but is a little odd. – outis Oct 29 '09 at 05:01
  • @outis If it is autoreleased, then isn't using it in the caller method incorrect. Because the scope of the method that actually created the NSError * and assigned it to the out parameter NSError ** has finished with the method call and we use it after that in the caller. – SayeedHussain Aug 22 '13 at 10:12
  • @paranoidcoder: no, because 1) you're describing a different scenario than casademora's, who is creating the NSError in the caller, and using it in the called, and 2) the NSError is dynamically allocated, so it's not an [automatic variable](http://stackoverflow.com/q/13415321/90527) (only local variables are automatic) and won't be freed when the method exits. Autoreleased objects are reclaimed when their autorelease pool is drained. The point is somewhat moot these days, as you should probably be using ARC (unless you want to support old platforms). – outis Aug 23 '13 at 21:23
6

Read the memory rules on developer.apple.com Never trust anyone restating them like 'you earlier called copy/alloc/retain' - this is not the rule, which actually says something like 'you recieved the object via a method with copy, new or alloc as part of the name'. Again, don't trust me, read developer.apple.com

As to NSError * * , thats just wrong. The METHOD takes an NSError * * as its argument, that is a pointer to an NSError * . Its the POINTER TO THE NSError * that will be populated with the address of an NSError that comes from somewhere and you have no right to assume where.

You can only pass a pointer to an NSError * - anything else is wrong.

Nor should you assume the NSError is auto-released. It may be a singleton, it could be any number of alternates. All you need to know is that 'you didn't retain it, you don't need to release it'.

Jeff
  • 181
  • 1
  • The Ownership Policy (http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmObjectOwnership.html#//apple_ref/doc/uid/20000043-SW1) is that methods with copy/alloc/new imply ownership (and retain explicitly declares ownership), which is what determines who sends release messages. – outis Oct 29 '09 at 05:35
  • 3rd parties aren't required to follow this policy, but Apple's recommendation is to autorelease a created NSError before returning it (http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/CreateCustomizeNSError/CreateCustomizeNSError.html#//apple_ref/doc/uid/TP40001806-CH204-SW5) – outis Oct 29 '09 at 05:36
  • Hence "generally autoreleased" and "general rule". – outis Oct 29 '09 at 05:37
4

You haven't allocated memory for the error, so you don't need to release it. As a rule, the framework usually adds autorelease to any objects it creates.

Ken Pespisa
  • 21,989
  • 3
  • 55
  • 63