NSTextView会更改您背后的数据

时间:2015-05-18 08:38:44

标签: objective-c macos cocoa nstextview

我有一个非常简单的玩具应用程序,只有一个文本视图和一个按钮。

xib

这些由AppController类控制,看起来像这样

// AppController.h
#import <Cocoa/Cocoa.h>

@interface AppController : NSObject <NSTextViewDelegate>

@property IBOutlet NSTextView *textView;
-(IBAction)apply:(id)sender;

@end
// AppController.m
#import "AppController.h"

@implementation AppController {
    NSString *name;
}

-(void)awakeFromNib {
    name = @"Bob";
    _textView.string = name;
}

-(IBAction)apply:(id)sender {
    name = _textView.string;
    NSLog(@"%@", name);
}

-(void)textDidChange:(NSNotification *)notification {
    NSLog(@"%@", name);
}

@end

当用户在textView中输入新值并单击“应用”按钮时,我希望实例变量名称获取此新值。这是我第一次点击“应用”按钮时发生的情况。

但是下次我更改textView中的值时,实例变量会自动更改,而无需用户点击“应用”按钮!

这是一种不受欢迎的行为,因为我没有进行任何绑定。事实上,如果我将textView更改为textField,则不会发生奇怪的行为。

所以似乎NSTextView做了一些奇怪的非自愿绑定。有人可以解释这种奇怪的行为以及如何解决这个问题。我不希望textView在我背后改变我的数据。

我在YouTube上制作了一个视频,其中显示了textField和textView之间的行为差​​异,您可以在https://youtu.be/qenGKp_L4qs找到它。

我已经检查了Xcode6和Xcode5,并且两者都发生了奇怪的行为。

如果您想在自己的机器上测试它,请不要忘记将NSTextView的委托属性与IB中的AppController连接。

1 个答案:

答案 0 :(得分:4)

这一行:

name = _textView.string;

使您的实例变量引用文本视图在内部使用的同一对象。来自documentation for the string property of NSTextNSTextView继承自:)

  

出于性能原因,此方法返回文本对象的当前后备存储。如果要在操作文本存储时维护此快照,则应复制相应的子字符串。

当你说'#34;我不希望textView改变我背后的数据时,你就错了。文本视图正在更改数据,您(不明智地)将其视为您自己的数据。

你应该a)为你的内部状态创建一个(可能是私有的)属性,b)使用该属性的copy属性,c)使用self.name = _textView.string;分配给你的内部状态。< / p>

如果您不想这样做,则必须至少使用name = [_textView.string copy];手动复制字符串。