我有一个 NSTextField 的子类,并且设置了 LineBreakMode。
在我的 Mac 上使用 Yosemite 运行良好 我的一位用户在 Mavericks 上发生崩溃
由于未捕获的异常“NSInvalidArgumentException”而终止应用,原因:“-[XTextField setLineBreakMode:]:无法识别的选择器发送到实例 0x7fc784548ad0”
这一轮我该如何工作?
子类的头文件
#import <Cocoa/Cocoa.h>
@interface XTextField : NSTextField
- (void)setText:(NSString *)text
@end
实现
#import "XTextField.h"
@implementation XTextField
- (void)setText:(NSString *)text
{
if (text)
{
[self setStringValue:text];
}
else
{
[self setStringValue:@""];
}
}
- (instancetype)initWithFrame:(NSrect)frame
{
if(self = [super initWithFrame:frame])
{
[self setEditable:NO];
[self setSelectable:NO];
[self setDrawsBackGround:NO];
[self setBezeled:NO];
}
return self;
}
@end
调用代码:
XTextField* myLabel = [[XTextField alloc]initWithFrame:myFrame];
[myLabel settext:@"text text text"];
[myLabel setLineBreakMode:NSLineBreakByTruncatingTail];
最佳答案
这里有很多问题需要回答。正如错误消息所示,问题在于 setLineBreakMode:
选择器被发送到无法识别该选择器的对象。可能发生什么情况会导致这种情况?弄清楚这样的事情需要批判性思维和侦探工作。这里有一些想法。
-setLineBreakMode:
似乎实际上并不是由NSTextField
实现的;据我所知,它是 NSCell 和 NSMutableParagraphStyle 的方法。如果您有NSTextField
(或其子类),您通常会调用[[myTextField cell] setLineBreakMode:...]
,但您的代码片段不会表明您正在这样做。因此,除非您在子类中实现了此方法(您没有声明您这样做了),否则这可能是崩溃的原因。也许您在 Mac 上没有看到崩溃,因为无论出于何种原因,该代码路径都没有被命中?或者也许苹果在 Yosemite 私下实现了这种方法,但没有在 Mavericks 实现?谁知道。您是否在该行收到编译器的警告,指出该对象不响应该选择器?不要忽略编译器警告。您发布的代码看起来像是在类对象上调用
setLineBreakMode:
,而不是在类的实例上;通常类以大写字母开头,而实例以小写字母开头。遵守这样的编码约定可以让每个人都不再感到困惑。如果你的子类确实被命名为 NSTextFieldSubClass,那么我同意 @MichaelDautermann 的观点,即你永远不应该使用 NS 前缀来命名类;这既令人困惑又自找麻烦,因为据您所知,Apple 有一个具有完全相同名称的私有(private)子类。以NS
开头的类名由 Apple 保留。您认为明显命名为 NSTextFieldSubClass 的变量中的对象可能根本不是您的子类的实例,或者已被释放(并且可能被替换为同一地址的新对象),或类似的问题,这就是它不响应选择器的原因。您可以通过打开 NSZombieEnabled、在调试器中检查它、添加它的 NSLog 来调查此问题(可能在你的子类),或许多其他技术。
这一切都相当模糊,但问题也很模糊。您需要至少发布子类的代码、实例化子类的代码以及崩溃行周围的代码,以获得更具体的帮助。我们无法读懂您的想法,而错误的根源很可能就在这些地方之一。
关于objective-c - NSTextField 子类在 setLineBreakMode : method 上崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32882703/