我有一个使用自动引用计数的类。在课堂上,我有一个如下所述的财产。当我为班级设置提醒时,我希望发生更改按钮标题的副作用。
这是我的代码:
<。>文件中的:
@property(nonatomic,strong)Reminder* reminder;
.m文件中的: @synthesize提醒;
-(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");
}
}
我知道如果没有ARC,我会做这样的事情:
-(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");
}
}
我是否需要在启用ARC的setter方法中执行其他操作以确保正确保留强变量?
答案 0 :(得分:5)
你不需要为这样的副作用编写自己的setter。使用KVO!
使拥有该按钮的控制器观察此对象的reminder
属性:
[reminderOwner addObserver:self
forKeyPath:@"reminder"
options:NSKeyValueObservingOptionNew
context:NULL];
options
argument指定在观察时您想要传递的被观察物体状态的信息。
然后,只要此属性更改值,您的控制器就会被通知(请注意,只有在以“符合键值”的方式设置属性时才会发生这种情况,最方便的方法是通过setter方法* - 更改ivar直接不算数。)
您需要在控制器中实施observeValueForKeyPath:ofObject:change:context:
:
- (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");
}
}
}
哦,而且,呃,回答你的实际问题,我相信你的记忆管理很好。 reminder
被合成为__strong
- 限定变量,这意味着ARC将保留您放置的任何内容。
*这就是为什么你听说不要在init
和dealloc
中使用setter。