【问题标题】:Why doesn't this property update in UI?为什么这个属性在 UI 中没有更新?
【发布时间】:2014-03-17 11:23:02
【问题描述】:

我有一个简单的应用程序:绑定到item.title 的文本框。此属性公开为NSString,但在内部是NSMutableString

问题:对 title 属性的更改未反映在 UI 中。

这里是item的实现:

@interface Item : NSObject
{
    NSMutableString *_title;
}

@property NSString *title;

@end

以及实现:

@implementation Item

-(void)mutateTitle
{
    [self willChangeValueForKey:@"title"];
    [_title appendString:@"mutated"];// this does not work
    //_title = [[NSMutableString alloc] initWithString:@"new instance"];// this works
    [self didChangeValueForKey:@"title"];
}

-(NSString *)title
{
    NSLog(@"get title returning: %@", _title);
    return _title;
}
-(void)setTitle:(NSString *)title
{
    _title = [[NSMutableString alloc] initWithString:title];
}

@end

当一个按钮被按下时,我们发送mutateTitle给item,它改变标题,并通知KVO属性改变。

UI 确实会响应更改,当调用 title 时,我们会返回正确的字符串。

但是 UI 并没有反映这些变化。

请注意,如果我取消注释将新实例分配给 _title 的行,则更新会正常进行。

另外,如果title 返回_title副本,它也可以正常工作。

为什么会这样?有什么方法可以让我按照自己的意愿完成这项工作吗?


*edit: title 被分配到代码的其他地方;不是nil

【问题讨论】:

  • KVC 最好使用self.propertyName
  • 我相信 _property 不像 self.property 那样做 KVC。

标签: objective-c cocoa binding key-value-observing


【解决方案1】:

那是因为如果可变字符串发生了变异,但属性没有改变(指针仍然指向同一个对象),那么 KVC 不会认为它是真正的改变。这可能是出于效率原因(如果调用了 didChangeValueForKey: 但字符串相同,则无需更新 UI)。

我建议根本不要使用可变字符串,它不符合您的目的。只需使用一个普通的字符串,而不是改变它重新分配它:

-(void)mutateTitle
{
    [self willChangeValueForKey:@"title"];
    _title= [_title stringByAppendingString: @"mutated"];
    [self didChangeValueForKey:@"title"];
} 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    • 2011-04-16
    • 2018-03-13
    • 2015-10-24
    • 1970-01-01
    相关资源
    最近更新 更多