Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to safely pass a context object in an UIAlertView delegate?

In my application I use a UIAlertView to display to the user a message and some options. Depending on the button pressed, I want the application to perform something on an object. The sample code I use is...

-(void) showAlert: (id) ctx {
    UIAlertView *baseAlert = [[UIAlertView alloc] 
                          initWithTitle: title
                          message: msg
                          delegate:self
                          cancelButtonTitle: cancelButtonTitle
                          otherButtonTitles: buttonTitle1, buttonTitle2, nil];
    //baseAlert.context = ctx;
    [baseAlert show];
    [baseAlert release];
}


- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
    if (buttonIndex == 1) {
        id context = ...;//alertView.context;
        [self performSelectorOnMainThread:@selector(xxx:) withObject: context waitUntilDone: NO];
    }
}

Is there any way to pass an object into the delegate as a context object? or maybe some other way?

I could add the property on the delegate but the same delegate object is being used by many different alert views. For this reason I would prefer a solution where the context object is attached to the UIAlertView instance and carried across to the delegate as part of the UIAlertView object.

like image 300
Panagiotis Korros Avatar asked Jun 30 '09 12:06

Panagiotis Korros


2 Answers

I still think storing it locally is the best solution. Create a class local NSMutableDictionary variable to hold a map of context objects, store the context with UIAlertView as the key and the context as the value.

Then when the alert method is called just look into the dictionary to see which context object is related. If you don't want to use the whole Alert object as a key, you could use just the address of the UIAlertView object:

NSString *alertKey = [NSString stringWithFormat:@"%x", baseAlert];

The address should be constant on the phone. Or you could tag each alert as the other poster suggested and use the tag to look up a context in the map.

Don't forget to clear out the context object when you are done!

like image 51
Kendall Helmstetter Gelner Avatar answered Nov 03 '22 21:11

Kendall Helmstetter Gelner


A complete implementation that allows you to pass context:

@interface TDAlertView : UIAlertView
@property (nonatomic, strong) id context;
@end

@implementation TDAlertView
@end

And a usage example, note how we pre-cast the pointer:

@implementation SomeAlertViewDelegate
- (void)alertView:(TDAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
     NSLog(@"%@", [alertView context]);
}
@end
like image 10
mxcl Avatar answered Nov 03 '22 19:11

mxcl