NSTextField 子类在 setLineBreakMode: 方法上崩溃

NSTextField Subclass Crashes on setLineBreakMode: method

我有一个 NSTextField 的子类,我设置了 LineBreakMode。

在我的 mac 和 Yosemite 下工作正常 我的一位用户在 Mavericks

上崩溃

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[XTextField setLineBreakMode:]: unrecognized selector sent to instance 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: 选择器被发送到无法识别该选择器的对象。会发生什么会导致这种情况?弄清楚这样的事情需要批判性思维和侦探工作。这里有一些想法。

  1. -setLineBreakMode:好像并没有真正被NSTextField实现;据我所知,它是 NSCellNSMutableParagraphStyle 的方法。如果您有 NSTextField(或它的子 class),您通常会调用 [[myTextField cell] setLineBreakMode:...],但您的代码片段并不表示您正在这样做。所以除非你在你的 subclass 中实现了这个方法——你没有声明你做了——这可能是崩溃的原因。也许您没有在 Mac 上看到崩溃,因为无论出于何种原因,此代码路径都没有受到影响?或者也许 Apple 在 Yosemite 中私下实现了此方法,但在 Mavericks 中没有实现?谁知道。您是否在该行收到来自编译器的警告,说该对象不响应该选择器?不要忽略编译器警告。

  2. 您 post 编辑的代码看起来像是在 class 对象上调用 setLineBreakMode:,而不是在 class 的实例上;通常 classes 以大写字母开头,而实例以小写字母开头。像这样遵守编码约定可以减少每个人的困惑。如果你的 subclass 真的被命名为 NSTextFieldSubClass,那么我同意@MichaelDautermann 的观点,你永远不应该用 NS 前缀命名 classes;这既令人困惑又自找麻烦,因为据您所知,Apple 有一个私有 subclass 正是这个名字。 Class 以 NS 开头的名称由 Apple 保留。

  3. 可能是你认为在你显然命名为 NSTextFieldSubClass 的变量中的对象根本不是你的 subclass 的实例,或者已经已释放(并且可能被同一地址的新对象替换)或某些此类问题,这就是它不响应选择器的原因。您可以通过打开 NSZombieEnabled、在调试器中检查它、添加它的 NSLog(可能在您的 subclass 中添加 -description 方法)来调查此问题,或者许多其他技术。

这一切都非常模糊,但问题是模糊的。您至少需要 post 子程序的代码 class、实例化子程序的代码 class 以及崩溃行周围的代码,以获得更具体的帮助.我们无法读懂您的想法,错误的根源很可能就在其中一个地方。