views:

145

answers:

2

Hi

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

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

Suppose a field for store country names. The popover first show a list of continents, when the user select 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's 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's 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 it is wrong?.

+1  A: 

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

vodkhang
A: 

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.

hotpaw2