Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Using your example, the method signature would be:</p> <pre><code>-(BOOL)save:(NSError**)error; </code></pre> <p>Now, when using double pointers, you need to be defensive in your programming. First, you must make sure that the value of <code>error</code> is not <code>nil</code>, then <code>*error</code> is <code>nil</code>. You must do this because you don't know what to do memory management wise with an existing object. For example:</p> <pre><code>NSError *error = nil; [self save:&amp;error]; </code></pre> <p>would be correct. But</p> <pre><code>NSError *error = [[NSError alloc] init]; [self save:&amp;error]; </code></pre> <p>is a problem because your <code>save:</code> method won't if <code>error</code> is <code>retained</code> or <code>autoreleased</code>. If you <code>release</code> it and it's <code>autoreleased</code> then your app will eventually crash. Conversely, if you don't <code>release</code> it and it is <code>retained</code> you leak memory. I recommend checking for this with an assert so that the problem is taken care of quickly before code is checked in.</p> <pre><code>NSAssert(!error || !*error, @"*error must be nil!"); </code></pre> <p>Finally, when setting <code>*error</code> you must make sure that <code>error</code> is not <code>nil</code>. You are never permitted to set the value of memory address <code>0x0</code>. If you don't check and if you pass <code>nil</code> into the method, you <em>will</em> crash if you try to set it.</p> <pre><code>if (error) { *error = [NSError ...]; return NO; } </code></pre> <p>To return an array I would do something like this:</p> <pre><code>-(BOOL)throwMultipleErrors:(NSError **) error { NSAssert(!error | !*error, @"*error must be nil"); NSMutableArray *errorList = nil; if (error) errorList = [NSMutableArray array]; [errorList addObject:@"First Error"]; [errorList addObject:@"Second Error"]; [errorList addObject:@"Third Error"]; if (error &amp;&amp; [errorList count] &gt; 0) { *error = [NSError errorWithDomain:@"Some error" code:0 userInfo:@{@"suberrors" : [NSArray arrayWithArray:errorList]}]; return NO; } return YES; } </code></pre> <p>Note that the return array is immutable and is instantiated inside the method. There's really no reason for this array to be mutable outside of this method and for the array to be instantiated outside of it. Encapsulating the array in an <code>NSError</code> permits it to easily fit into an existing chain of <code>NSError</code> methods.</p> <p>Notes</p> <p>Of course, you would actually throw your <code>[self save:&amp;error];</code> call into an <code>if()</code> statement to check the return value. Do note, however, that we pass in <code>&amp;error</code> rather than just <code>error</code>. This is because we need to pass in the <em>pointer</em> to <code>error</code>, not <code>error</code> itself. <code>&amp;error</code> reads as "The address of error."</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload