0

我有一个简单的 Cocoa 应用程序(压缩后 39 KB),它由一个应用程序委托 ( AppDelegate) 和一个NSString类别(以及一个什么都不做的默认窗口)组成。

在其init方法中,AppDelegate创建一个NSSavePanel. 在执行此操作之前和之后,它会记录通过NSString类别方法修剪掉空格和换行符的字符串的长度:stringByTrimmingWhitespace.

该字符串由空格和换行符组成。我的类别方法应该修剪所有这些字符,从而产生一个长度为 0 的字符串。

NSSavePanel创建之前,我的stringByTrimmingWhitespace方法被调用并返回一个长度为 0 的字符串,正如预期的那样。创建之后NSSavePanel,我的stringByTrimmingWhitespace方法似乎没有被调用,并且调用的任何方法都不会修剪换行符。但是,NSString执行完全相同的操作的不同类别方法 - <code>stringByTrimmingWhitespaceAndNewlines - 被调用并按预期工作。

我完全不知道是什么导致我stringByTrimmingWhitespace没有被调用或如何修复它(除了重命名它,这是我所做的)。我还担心其他类上的其他类别方法可能会被丢弃。有谁知道这里发生了什么?

4

1 回答 1

6

似乎NSSavePanel是在 NSString 上加载一个类别供自己使用,其名称与您的-[NSString(TurnerAdditions) stringByTrimmingWhitespace]方法冲突。您可以使用以下代码进行验证:

NSString *foo = @"!";
NSLog(@"Responds to '-stringByTrimmingWhitespace': %@", [foo respondsToSelector:@selector(stringByTrimmingWhitespace)] ? @"YES" : @"NO");
NSSavePanel *panel = [NSSavePanel savePanel];
NSLog(@"Responds to '-stringByTrimmingWhitespace': %@", [foo respondsToSelector:@selector(stringByTrimmingWhitespace)] ? @"YES" : @"NO");

为什么它的行为与您的不同有点奇怪(编辑:不,不是,请参阅@rdelmar 的评论)。

您应该始终在您的类别中为方法名称添加前缀,特别是对于这样的实例。Cocoa 命名约定相当明确,这使得它很可能发生名称冲突。由于处理类别的方式(例如,它们可以在您不知情的情况下在应用程序的执行过程中加载),编译器很难/不可能提供冲突错误。

于 2013-03-26T05:19:36.507 回答