在 NSDocument 中设置行终止符字符串?

发布于 2024-10-07 21:37:54 字数 2543 浏览 2 评论 0原文

(这个问题是根据一些进一步研究后的 NSTextView 问题重写的)

更新:您可以在此处下载一个显示问题的非常基本的项目:

http://w3style.co.uk/~d11wtq/DocumentApp.tar.gz

(执行 grep -c " \r" file.txt 您保存的文件中,以获取发生 \r 的行数...重复 \n)。

我已经意识到 NSDocument 创建的所有文件都有 \r 是行结尾,而不是标准的 \n,即使 NSData 我的文档子类返回不包含 \r,它只包含 \n。有没有办法配置这个?

我认为 Mac 现在使用了 UNIX 行结尾,所以 AppKit 仍然使用过时的 Mac 结尾似乎很奇怪。奇怪的是,NSDocument 请求 NSData,然后通过转换行结尾来不友善地破坏 NSData

切换到 \r 是在生成 NSData 之后发生的,因此 NSDocument 本身正在对字节进行一些替换:

 const char *bytes = [data bytes];
 int i, len;
 for (i = 0, len = [data length]; i < len; ++i) {
  NSLog(@"byte %d = %02x", i, bytes[i]);
 }

输出(注意 0a 是 \n 的十六进制值):

> 2010-12-17 12:45:59.076
> MojiBaker[74929:a0f] byte 0 = 66
> 2010-12-17 12:45:59.076
> MojiBaker[74929:a0f] byte 1 = 6f
> 2010-12-17 12:45:59.076
> MojiBaker[74929:a0f] byte 2 = 6f
> 2010-12-17 12:45:59.077
> MojiBaker[74929:a0f] byte 3 = 0a
> 2010-12-17 12:45:59.077
> MojiBaker[74929:a0f] byte 4 = 62
> 2010-12-17 12:45:59.077
> MojiBaker[74929:a0f] byte 5 = 61
> 2010-12-17 12:45:59.077
> MojiBaker[74929:a0f] byte 6 = 72
> 2010-12-17 12:45:59.077
> MojiBaker[74929:a0f] byte 7 = 0a

如果 NSDocument 将请求 NSData 那么它应该尊重这一点而不是修改它。

以下是我的文档中的方法 -dataOfType:error: 方法的完整代码:

    -(NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
 NSString *string = [textView string];

 // DEBUG CODE...
 NSArray *unixLines = [string componentsSeparatedByString:@"\n"];
 NSArray *windowsLines = [string componentsSeparatedByString:@"\r\n"];
 NSArray *macLines = [string componentsSeparatedByString:@"\r"];

 NSLog(@"TextView has %d LF, %d CRLF, %d CR", [unixLines count] - 1, [windowsLines count] - 1, [macLines count] - 1);

 NSData *data = [NSData dataWithBytes:[string cStringUsingEncoding:NSUTF8StringEncoding]
          length:[string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];

 const char *bytes = [data bytes];
 int i, len;
 for (i = 0, len = [data length]; i < len; ++i) {
  NSLog(@"byte %d = %02x", i, bytes[i]);
 }

 if (data != nil) {
  [textView breakUndoCoalescing];
 }

 return data;
}

(This question has been rewritten from an issue with NSTextView following some further research)

UPDATE: You can download a very basic project that displays the issue here:

http://w3style.co.uk/~d11wtq/DocumentApp.tar.gz

(Do a grep -c "\r" file.txt on the file you save to get a line count where \r occurs... repeat for \n).

I've realised all files created by NSDocument have \r is line endings, not the standard \n, even though the NSData my document subclass returns does not contain \r, it only contains \n. Is there a way to configure this?

I thought Macs used UNIX line endings these days, so it seems weird that AppKit is still using the antiquated Mac endings. Weirder is that NSDocument asks for NSData, then rather unkindly corrupts that NSData by transforming the line endings.

The switch to \r is happening after producing NSData, so NSDocument itself is doing some replacements on the bytes:

 const char *bytes = [data bytes];
 int i, len;
 for (i = 0, len = [data length]; i < len; ++i) {
  NSLog(@"byte %d = %02x", i, bytes[i]);
 }

Outputs (note 0a is the hex value of \n):

> 2010-12-17 12:45:59.076
> MojiBaker[74929:a0f] byte 0 = 66
> 2010-12-17 12:45:59.076
> MojiBaker[74929:a0f] byte 1 = 6f
> 2010-12-17 12:45:59.076
> MojiBaker[74929:a0f] byte 2 = 6f
> 2010-12-17 12:45:59.077
> MojiBaker[74929:a0f] byte 3 = 0a
> 2010-12-17 12:45:59.077
> MojiBaker[74929:a0f] byte 4 = 62
> 2010-12-17 12:45:59.077
> MojiBaker[74929:a0f] byte 5 = 61
> 2010-12-17 12:45:59.077
> MojiBaker[74929:a0f] byte 6 = 72
> 2010-12-17 12:45:59.077
> MojiBaker[74929:a0f] byte 7 = 0a

If NSDocument is going to ask for NSData then it should respect that and not modify it.

Here's the full code from the method: -dataOfType:error: method in my document:

    -(NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
 NSString *string = [textView string];

 // DEBUG CODE...
 NSArray *unixLines = [string componentsSeparatedByString:@"\n"];
 NSArray *windowsLines = [string componentsSeparatedByString:@"\r\n"];
 NSArray *macLines = [string componentsSeparatedByString:@"\r"];

 NSLog(@"TextView has %d LF, %d CRLF, %d CR", [unixLines count] - 1, [windowsLines count] - 1, [macLines count] - 1);

 NSData *data = [NSData dataWithBytes:[string cStringUsingEncoding:NSUTF8StringEncoding]
          length:[string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];

 const char *bytes = [data bytes];
 int i, len;
 for (i = 0, len = [data length]; i < len; ++i) {
  NSLog(@"byte %d = %02x", i, bytes[i]);
 }

 if (data != nil) {
  [textView breakUndoCoalescing];
 }

 return data;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

歌入人心 2024-10-14 21:37:54

NSDocument 不关心行终止;它是一个半抽象类,旨在进行子类化。它本身对文件格式没有任何影响。

它是 NSDocument 子类的特定实现(恰好读取和写入纯文本),它将关心行终止字符。

NSDocument doesn’t care about line termination; it’s a semi-abstract class, designed to be subclassed. By itself it imposes nothing on a file format.

It’s the particular implementation of an NSDocument subclass - one that happens to read and write plain text - that will care about line termination characters.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文