为什么我的命令行pgm看不到这个文件?

jos*_*uth -2 load file objective-c nsstring

很奇怪的问题.我一直在测试我的小命令行程序,它读取一个文件并解析它,它与我的测试数据工作正常,但是当我追求真实的东西时,它找不到文件.

原始文件是通过文本编辑放在一起的文本文件,实际文件是以MS-Dos格式从Microsoft Word保存的.当我试图读取MS Word文件时,它找不到它.我没有收到错误但是从文件加载方法中得到了一个nil字符串.然后我将我的测试文件重命名为相同的名称,它获得了原始测试数据.咦?在最坏的情况下,我认为我会看到某种奇怪的数据加载到我的字符串中......不是零.

这是代码片段的程式化部分.请忽略数据文件NSString周围的"捕获和释放"代码......我意识到我不需要这样做,这不是问题的关键.

datafilename设置为'config1.txt'.

(NSString*) OpenEntryFile: (NSString*) pathname withdatafilename: (NSString*) datafilename {    

NSStringEncoding encoding;
NSError* error = nil;
NSString* inputdatafile;
NSString* response;
NSString *homeDir    = NSHomeDirectory();

NSString *fullPath = [homeDir stringByAppendingPathComponent:datafilename];

filepointer = 0;
[Datafile release];
inputdatafile = [NSString stringWithContentsOfFile: fullPath usedEncoding:&encoding error:&error];

Datafile = [inputdatafile copy];

response = [NSMutableString stringWithString: @"OK"];

if (error) {response = [NSMutableString stringWithString: @"ERROR"];};

if ([Datafile length] < 60) {response = [NSMutableString stringWithString: @"SHORT"];};

return response;
}
Run Code Online (Sandbox Code Playgroud)

bbu*_*bum 28

这段代码有很多问题;

  • Datafile 应该 dataFile

  • if(error)是错的; 只有通过检查返回值才能知道是否生成了错误.

  • 没有必要使用NSMutableString您的回复.只需直接使用常量字符串即可.

  • 没有必要将数据复制为读取stringWithContentsOfFile:; 只保留结果字符串(如果你得到一个).

  • 如果你准备好nilinputdatafile,那么就会产生一个错误.即返回的字符串不能为nil而不error包含问题的描述.

即这将始终输出字符串或错误:

if (inputdatafile)
    NSLog(@"%@", inputdatafile);
else
    NSLog(@"error %@", error);
Run Code Online (Sandbox Code Playgroud)

来自评论:

 if ([error code]) {response = [NSMutableString stringWithString: @"ERROR"];}
Run Code Online (Sandbox Code Playgroud)

这是完全错误的.

规则是您必须在检查错误之前检查返回值.永远无例外.

否则将导致崩溃和其他错误行为.

  • 有效的代码可能仅仅因为症状而起作用.你读错了文档; 返回值表示成功/失败.该错误描述了原因.如果为error参数传递NULL,则系统不会以创建错误为代价.如果***传递一个错误参数,系统会*不保证它会保留你赋给它的任何值(你的`error = nil`是没有意义的).重要的不是你对它的看法,它的工作方式.你可能会发现它"懒惰的出路",但是 - 在那 - 你也错了. (12认同)
  • 无论您如何使用数据.您正在调用系统API,如果您不遵循该API的文档化和设计模式,您的代码将只能巧合地正确运行,并且可能仅在您下一次软件更新之前(或之后的行为)按预期运行那).这是对事实的陈述,而不是个人意见. (12认同)
  • 我想特别注意@bbum先前说过的事情:"返回值表示成功/失败.该错误描述了原因."在查看方法结果之前查看错误是在知道失败之前询问失败的原因.直到你知道它失败了(方法返回`NO` /`nil`),它失败原因的答案并不能保证有意义.所以,在确定方法失败之前,不要费心去查看失败的原因. (8认同)
  • 虽然我同意有些是相对较小的,但我指出的每一个问题都是非常真实的,并且表明对系统的工作方式缺乏了解(或者至少与典型模式缺乏一致性).您无法直接查看错误对象.您必须检查返回值,然后仅在返回值为nil/NO*时才处理错误*. (7认同)
  • @Joe Ruth:作为一个忠告,我会去做一些关于@bbum是谁,他为谁工作以及他的工作方式的谷歌搜索.然后考虑告诉他他应该更好奇或者猜测他如何运行时.:) (7认同)
  • 返回值始终是方法的主要焦点(设计决策).使用NSError消除了所有歧义; 从来没有*没有结果也没有错误的情况.这使编码和测试矩阵更简单,因为只有一个且只有一个执行路径产生有效结果或没有结果; 错误是*完全元数据*.并且,是的,正交地,有非常真实和可测量的性能问题,通过为错误传递NULL并仅检查PASS/FAIL来解决. (6认同)
  • @Joe Ruth:认真对待bbum给你的知识.他没有给你一个拼图的"线索".他正在分享他的知识,并为此提供了成为更好的Cocoa开发人员的途径. (5认同)
  • @Jonathan那,是的,绝对正确; 与可变字符串相比,`NSString`非常有效.并且,是的,将NULL传递给`NSError**'参数可以在一些深奥但有用的地方节省大量的CPU /内存周期. (4认同)
  • *这种方式不起作用,就是这样.*并且有很好的理由.你可能不同意他们的观点,但是将它们视为一种kludge或者缺乏仔细考虑的结果是错误的. (4认同)
  • 因为返回`void`的方法根本不返回任何内容; 它完全是未定义的.如果你的编译器在你试图查看返回值时没有大肆抱怨,那你就错了(除非你做的事与众不同).当没有什么更有意义时,为什么要归还什么?返回值也强制同步,可能不需要. (3认同)
  • @Joe Ruth"实际上所有其他计算机框架都不能以这种方式工作"至少Windows API以这种方式工作:在确保最后一个过程调用实际失败之前调用GetLastError()可能基本上返回任何内容.有些API设置了最后一个错误,有些则没有.如果最后一次调用没有真正失败,则无法保证该值是合理的. (3认同)
  • 也就是说,你的代码,只是巧合,而不是系统的规则.(顺便说一下,我很好奇为什么你到处创建`NSMutableStrings` - 保证效率低于使用常量字符串?) (2认同)
  • @Joe只是想注意@bbum关于效率的一点与你的`NSError`混淆无关,而是与你对`NSMutableString`的混淆使用有关.既然你实际上并没有以任何方式附加或以其他方式改变你的`NSMutableString`对象,那么使用它们是没有意义的!Cocoa可变性语义与重新分配无关(这就是你正在做的事情).因此,`NSString`将正常工作而不会改变其他任何东西.这不是某个人在你身上拉扯旧**效率**的例子.这只是常识. (2认同)
  • 这是一个你正在使用的强大破解框架.坦率地说,如果它是我的应用程序,我会尽我所能来修复或删除所述框架.如果框架搞砸了那么基本的东西,我就不得不怀疑它的其余部分也是无用的.我得到了你来自哪里,但面对如此糟糕的质量,这似乎是一场徒劳的战斗. (2认同)
  • @Joe Ruth"几乎所有其他计算机框架都不能以这种方式工作"所以?Cocoa*以这种方式工作,并且希望它以不同的方式工作并不会改变它.如果您真的想要更改它,请提交错误报告,并希望Apple的框架工程师决定接受您的建议并对所有框架进行全面检查.(提示:他们不会) (2认同)