0

As I understood, I should not be retaining a controller which is a delegate or datasource. I have made a UIPickerView, created in a property accessor as such:

-(UIPickerView *)projectPicker {
  if (_projectPicker != nil) {
      return _projectPicker;
  }

  //Create Picker View
  UIPickerView *picker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 185, 0, 0)];
  picker.showsSelectionIndicator = YES;
  //Create source and delegate
  NSString *titleForRow0 = NSLocalizedString(@"<<Make Selection>>", @"projectPicker nil Label 0");
  NSArray *titlesForFirstRows = [[NSArray alloc] initWithObjects:titleForRow0, nil];
  ProjectPickerDatasource *pickerSource = [[ProjectPickerDatasource alloc] initWithManagedObjectContext:self.managedObjectContext
                                                                                      selectedProject:self.currentProject
                                                                                andTitlesForFirstRows:titlesForFirstRows];
  [titlesForFirstRows release];
  picker.delegate = pickerSource;
  picker.dataSource = pickerSource;

  self.projectPicker = picker;

  [pickerSource release];
  [picker release];


  return _projectPicker;

}

This crashes reporting an attempt to access an unallocated instance of pickerSource. If I break the pickerSource component out as another property, thereby retaining it within this controller, it works perfectly. I did not think that was the proper implementation. Doesn't the pickerView retain it's delegate and datasource until it is destroyed?

Dean Davids
  • 4,174
  • 2
  • 30
  • 44
  • "Doesn't the pickerView retain it's delegate and datasource until it is destroyed?" No, it does not retain them. – albertamg Oct 02 '11 at 14:08
  • it is unanimous then. I was mistaken. Just seems then that this is a leak waiting to happen or memory held for no reason as I have to anticipate all possibilities and release/retain as appropriate. – Dean Davids Oct 02 '11 at 15:14

2 Answers2

1

If the Picker instantiates the datasource it is fine to retain it, it needs to be retained somewhere. Just be sure to release it.

Note, datasources are handled differently that delegates.

zaph
  • 111,848
  • 21
  • 189
  • 228
1

Mostly (as for as I know) the delegates are not retained by their classes. They are just assigned like this,

@property(nonatomic, assign) id <TheDelegateClass> delegate;

Its the responsibility of the caller to retain the delegate until the delegates job is over.

The answer for your question is UIPickerView doesn't retain its delegate. It expects you to retain it instead.

EmptyStack
  • 51,274
  • 23
  • 147
  • 178