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.
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.
The trouble is releasing memory. I set alertView.delegate to nil and call [self autorelease] to free the context object in -alertView:didDismissWithButtonIndex:.
THE QUESTION IS: What problems am I causing myself? I have a suspicion that I'm setting myself up for a subtle memory error.
Here is the simple version which only supports -alertView:clickedButtonAtIndex:
Use
- (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];
}
Interface
@protocol WantAlertViewContextDelegate <NSObject>
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex withContext:(id)context;
@end
@interface WantAlertViewContext : NSObject <UIAlertViewDelegate>
- (id)initWithDelegate:(id<WantAlertViewContextDelegate>)delegate context:(id)context;
@property (assign, nonatomic) id<WantAlertViewContextDelegate> delegate;
@property (retain, nonatomic) id context;
@end
Implementation
@implementation WantAlertViewContext
- (id)initWithDelegate:(id<WantAlertViewContextDelegate>)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