title: UIAlertView with a user supplied context and [self autorelease]
body: <p>I have looked over some ideas for how to supply a context to a UIAlertView. The common answers are save it in a dictionary or subclass UIAlertView. I don't like the idea of saving the context in a dictionary, it's the wrong place for the data. Subclassing UIAlertView is not supported by Apple, so by my standard, is not a good solution.</p>
  
  <p>I came up with an idea, but I'm not sure what to make of it. Create an instance of a context object that is the delegate of UIAlertView. The alert view context, in turn, has it's own delegate which is the view controller.</p>
  
  <p>The trouble is releasing memory. I set alertView.delegate to nil and call [self autorelease] to free the context object in -alertView:didDismissWithButtonIndex:.</p>
  
  <p><strong>THE QUESTION IS</strong>: What problems am I causing myself? I have a suspicion that I'm setting myself up for a subtle memory error.</p>
  
  <p>Here is the simple version which only supports -alertView:clickedButtonAtIndex:</p>
  
  <h3>Use</h3>
  
  <pre><code>- (void)askUserIfTheyWantToSeeRemoteNotification:(NSDictionary *)userInfo
  {
      [[[[UIAlertView alloc] initWithTitle:[userInfo valueForKey:@"action"]
                                   message:[userInfo valueForKeyPath:@"aps.alert"]
                                  delegate:[[WantAlertViewContext alloc] initWithDelegate:self context:userInfo]
                         cancelButtonTitle:@"Dismiss"
                         otherButtonTitles:@"View", nil] autorelease] show];
  }
  - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex withContext:(id)context
  {
      if (buttonIndex != alertView.cancelButtonIndex)
          [self presentViewForRemoteNotification:context];
  }
  </code></pre>
  
  <h3>Interface</h3>
  
  <pre><code>@protocol WantAlertViewContextDelegate &lt;NSObject&gt;
  - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex withContext:(id)context;
  @end
  
  @interface WantAlertViewContext : NSObject &lt;UIAlertViewDelegate&gt;
  - (id)initWithDelegate:(id&lt;WantAlertViewContextDelegate&gt;)delegate context:(id)context;
  @property (assign, nonatomic) id&lt;WantAlertViewContextDelegate&gt; delegate;
  @property (retain, nonatomic) id context;
  @end
  </code></pre>
  
  <h3>Implementation</h3>
  
  <pre><code>@implementation WantAlertViewContext
  - (id)initWithDelegate:(id&lt;WantAlertViewContextDelegate&gt;)delegate context:(id)context
  {
      self = [super init];
      if (self) {
          _delegate = delegate;
          _context  = [context retain];
      }
      return self;
  }
  - (void)dealloc
  {
      [_context release];
      [super dealloc];
  }
  - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
  {
      [self.delegate alertView:alertView clickedButtonAtIndex:buttonIndex withContext:self.context];
  }
  - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
  {
      alertView.delegate = nil;
      [self autorelease];
  }
  @synthesize delegate = _delegate;
  @synthesize context  = _context;
  @end
  </code></pre>