Bruno Berisso
Bruno Berisso

Reputation: 1091

objective-c delegates and events design (I don't get it)

I'm pretty new to the objective-c language (less than three months) but it is something that i really need to understand.

Suppose there is a controller (in a iOS environment) that manages a table view for input data from the user. The table must have editable cells and some features to make the value selection easier, for example a button that shows a popover with the possible values for a field.

Suppose there is a field to store country names. The popover first shows a list of continents; when the user selects a continent, the controller of the popover must show the countries of the previews selected continent.

Now, this popover appears in many places in the app so it will be nice if I can encapsulate it for later use. What i will expect for this popover is something like this:

...
@protocol MyPopoverDelegate<NSObject> {
-(void)didSelectCountry:(NSString *)countryName;
{
...
MyPopoverController *dataSelector = [[MyPopoverController] alloc] init];
dataSelector.dataType = CountryDataType;
dataSelector.delegate = self;
[dataSelector show];
[dataSelector release];
...

The problem here is the line [dataSelector release] because the code for managing the popover must stay alive until the country is selected. That's means the dataSelector variable must be a property of the caller class and that sucks.

The question then is: How can i organize situations like this to have a reusable controller?

Thanks

Edited after vodkhang answer:

Ok, that's a good one, but dataSelector still is a property. What if i do:

@implementation MyPopoverController

- (id)init {
...
[self retain];
...
}

- (void)popoverControllerDidDismissPopover: (UIPopoverController *)popoverController {
...
[delegate didFinishSelectingCountry:countryName];
[self release];
}

@end

I never see this behavior in objective-c, i feel that this is not the idea. Why is it wrong?.

Upvotes: 1

Views: 478

Answers (2)

hotpaw2
hotpaw2

Reputation: 70683

If you want some unique object reusable across an entire app from anywhere in the view hierarchy, you can make it a property of the app delegate, and let the app delegate own it (retain it when live, release it during memory warnings, etc.).

A self retained object may eventually run into problems if you ever port your code to a garbage collected environment.

Upvotes: 0

vodkhang
vodkhang

Reputation: 18741

One of the way you can do for delegate method is to have:

MyPopOverDelegate
    - (void)didFinishSelectingCountry:(NSString *)countryName popOver:(MyPopOver *)popOver;
    Caller.m

// the caller
- (void)viewDidLoad {
MyPopoverController *dataSelector = [[MyPopoverController] alloc] init];
dataSelector.dataType = CountryDataType;
dataSelector.delegate = self;
[dataSelector show];

}

- (void)didFinishSelectingCountry:(NSString *)countryName popOver:(MyPopOver *)popOver {
   // finish stuff
   [popOver release];
}

This way is used a lot like NSUrlConnection, UIImagePickerController

Upvotes: 1

Related Questions