我有一个简单的应用:绑定到item.title
的文本框。此属性公开为NSString
,但内部为NSMutableString
。
问题:对title
属性的更改未反映在用户界面中。
以下是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
,这会更改标题,并通知KVO房产更改。
UI确实响应了更改,并且在调用title
时,我们返回正确的字符串。
但是UI并没有反映出这些变化。
请注意,如果我取消注释我将新实例分配给_title
的行,则更新正常。
此外,如果title
返回_title
的副本,它也可以正常工作。
为什么会这样?有没有办法让我按照自己的意愿工作?
*编辑:title
正在代码的其他地方分配;它不是nil
。
答案 0 :(得分:1)
那是因为如果可变字符串发生变异,但属性没有改变(指针仍指向同一个对象),那么KVC将不会认为它是真正的变化。这可能是出于效率原因而做的(如果调用didChangeValueForKey:
但字符串相同,则无需更新UI)。
我建议不要使用可变字符串,它不适合您的目的。只需使用普通字符串,而不是改变它重新分配它:
-(void)mutateTitle
{
[self willChangeValueForKey:@"title"];
_title= [_title stringByAppendingString: @"mutated"];
[self didChangeValueForKey:@"title"];
}