With ARC, how to set a property with a side effect?

I have a class that uses automatic reference counting. Inside the class, I have a property as described below. When I set a reminder for a class, I need a side effect of changing the name of the button.

Here is my code:

in the .h file:

@property(nonatomic,strong)Reminder* reminder; 

in the .m file: @synthesize reminder;

  -(void)setReminder:(Reminder *)reminder_ { //what else do I need to do here? reminder = reminder_; if(!reminder.useSound.boolValue) { onOffButton.title = NSLocalizedString(@"Off", @"Off title"); }else { onOffButton.title = NSLocalizedString(@"On", @"On title"); } } 

I know that without ARC, I would do something like this:

 -(void)setReminder:(Reminder *)reminder_ { [reminder release]; reminder = [reminder_ retain]; if(!reminder.useSound.boolValue) { onOffButton.title = NSLocalizedString(@"Off", @"Off title"); }else { onOffButton.title = NSLocalizedString(@"On", @"On title"); } } 

Do I need to do anything else in my setter method that supports ARC to make sure the strong variable is saved correctly?

+4
source share
1 answer

You do not need to write your own setter for such side effects. Use KVO !

Make the controller that the button belongs to observe the reminder object:

 [reminderOwner addObserver:self forKeyPath:@"reminder" options:NSKeyValueObservingOptionNew context:NULL]; 

The options argument determines what information about the state of the observed object you would like to transmit during the observation.

Then your controller will be informed whenever this property changes value (note that this will only happen if the property is set in accordance with the key-value principle, the most convenient way is using the setter * method - changing ivar not directly taken into account).

You need to implement observeValueForKeyPath:ofObject:change:context: in your controller:

 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { // Distinguish between observations if necessary; you can also // use the |object| argument for this. if( [keyPath isEqualToString:@"reminder"] ){ // Update button text with contents of |change| dictionary Reminder * reminder = [change objectForKey:NSKeyValueChangeNewKey]; if(!reminder.useSound.boolValue) { onOffButton.title = NSLocalizedString(@"Off", @"Off title"); }else { onOffButton.title = NSLocalizedString(@"On", @"On title"); } } } 

Oh, and to answer your real question, I think memory management is fine. reminder synthesized as an __strong -qualified variable, which means that ARC will save everything you put there.


* That's why you heard not to use setters in init and dealloc .

+5
source

Source: https://habr.com/ru/post/1380313/


All Articles