使用ARC,如何正确设置具有副作用的属性?

时间:2011-11-09 02:25:37

标签: objective-c ios memory-management ios5 automatic-ref-counting

我有一个使用自动引用计数的类。在课堂上,我有一个如下所述的财产。当我为班级设置提醒时,我希望发生更改按钮标题的副作用。

这是我的代码:

<。>文件中的

@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方法中执行其他操作以确保正确保留强变量?

1 个答案:

答案 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将保留您放置的任何内容。


*这就是为什么你听说不要在initdealloc中使用setter。