arrays - 无法更改 Document 类中标签的 stringValue(基于文档的应用程序,Mac)

标签 arrays macos class cocoa document-based

我正在创建一个基于“测试”文档的应用程序,以了解有关它们如何工作的更多信息。我想加载我之前保存的数组。

- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
{
    NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSArray *array = [string componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];

    documentTitle.stringValue = [array objectAtIndex:0];

    // For testing
    NSLog(@"%@", array);
}

我加载了文件并获取了数据。我将数据转换为 NSString。该文件有多行,每行都有自己的值。第一行是文档标题。所以我创建了一个 NSArray 将每一行单独放入数组中。然后我将文档的第一行设置为 documentTitle 标签。出于测试目的,我也创建了一个 NSLog 函数。它必须记录数组。

问题是,当我运行代码时,它根本不执行任何操作。 documentTitle.stringValue 不变。但奇怪的是它确实记录了数组:

2015-09-22 16:57:40.098 DocBased Test[10765:277445] 
(
    "The awesome title!",
    "This is a document!"
)

我在 Document.h 中声明了 documentTitle,如下所示:

#import <Cocoa/Cocoa.h>

    @interface Document : NSDocument
    {
        IBOutlet NSTextField *documentTitle;
    }

@end

如果您需要在 Xcode 中查看项目,请点击以下链接:The link .

有人知道如何更改 Document 类中 documentTitle(或任何)标签的 stringValue 吗?

最佳答案

鉴于您的项目@ https://www.mediafire.com/?z6drw20suvt0re0 ,
我能够让它工作。写一个新的答案,因为我的原始答案已经非常庞大,并且更适合一般情况;而这个答案对于您的代码将非常具体

仅进行一些更改:
1) 由于 Document.xib 的所有者是 Document,因此您无需将文档对象拖入文档大纲中。所以我删除了它。
2)我选择了文件的所有者(文档),并设置了与您的 NSTextField 属性的连接
3)我删除了ivar

@interface Document : NSDocument
{
    IBOutlet NSTextField *documentTitle;
}

所以你的标题现在看起来像这样:

@interface Document : NSDocument

@end

4) 我在您的实现文件 (Document.m) 中创建了属性以及 NSString 属性(我将稍后解释)

@property NSString *titleString;
@property IBOutlet NSTextField *documentTitle;

5) 因此,如果您继续重写 -awakeFromNib 方法(只需在其中放置 NSLog 或其他内容),您实际上会看到 -awakeFromNib-readFromData 之后被调用。现在记住我所说的——对象已实例化,但在加载 View 并发送 -awakeFromNib 消息之前不会建立任何连接。

所以发生的事情是这样的:

  • 点击“打开”并选择一个文件
  • 您的文档已实例化
  • -readData... 在实例化期间立即调用,但尚未建立与 NSTextField 的连接,因此它是 nil
  • -awakeFromNib 被调用,以及从 Document 到任何 NSView 的连接(包括您的 NSTextField)已制作
  • 但已经太晚了。

所以解决办法很简单,
-readData 方法中,您应该将读取的字符串保存到 NSString 中,而不是设置 NSTextFieldstringValue 属性(我之前提到的)

然后,当您的 -awakeFromNib 被调用时,您只需访问您想要的值的 NSString 属性,然后设置 stringValue .

以下是更改的两个方法:

-(void)awakeFromNib
{
   if( self.titleString )
   {
      [self.documentTitle setStringValue:self.titleString];
   }
}

- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError {
    // Insert code here to read your document from the given data of the specified type. If outError != NULL, ensure that you create and set an appropriate error when returning NO.
    // You can also choose to override -readFromFileWrapper:ofType:error: or -readFromURL:ofType:error: instead.
    // If you override either of these, you should also override -isEntireFileLoaded to return NO if the contents are lazily loaded.

    NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSArray *array = [string componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];

    NSLog(@"\r%@", array);


    self.titleString = [array objectAtIndex:1];

    return YES;
}

如果您想在任何地方获得更多解释,请告诉我,但这对您有用:)

关于arrays - 无法更改 Document 类中标签的 stringValue(基于文档的应用程序,Mac),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32720397/

相关文章:

java - 数组中的搜索和删除错误

javascript - 使用 handlebars.js 模板以数组中的最后一项为条件

python - 将结构化数组转换为 numpy 数组以用于 Scikit-Learn

javascript - 谁在 JavaScript 中通过嵌套对象进行映射并删除键值对

.net - 从 SSL 证书中提取序列号

ruby-on-rails - 使用ctrl-n自动补全单词时,Vim随机出现段错误

objective-c - 更新 NSOpenGLView 大小

swift - 将具有嵌套自定义类的自定义类数组存储到 standardUserDefaults

javascript - React 组件表在更新状态后被渲染多次或重复

class - 结构中的私有(private)类