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:
选择器被发送到无法识别该选择器的对象。会发生什么会导致这种情况?弄清楚这样的事情需要批判性思维和侦探工作。这里有一些想法。
-setLineBreakMode:
好像并没有真正被NSTextField
实现;据我所知,它是 NSCell
和 NSMutableParagraphStyle
的方法。如果您有 NSTextField
(或它的子 class),您通常会调用 [[myTextField cell] setLineBreakMode:...]
,但您的代码片段并不表示您正在这样做。所以除非你在你的 subclass 中实现了这个方法——你没有声明你做了——这可能是崩溃的原因。也许您没有在 Mac 上看到崩溃,因为无论出于何种原因,此代码路径都没有受到影响?或者也许 Apple 在 Yosemite 中私下实现了此方法,但在 Mavericks 中没有实现?谁知道。您是否在该行收到来自编译器的警告,说该对象不响应该选择器?不要忽略编译器警告。
您 post 编辑的代码看起来像是在 class 对象上调用 setLineBreakMode:
,而不是在 class 的实例上;通常 classes 以大写字母开头,而实例以小写字母开头。像这样遵守编码约定可以减少每个人的困惑。如果你的 subclass 真的被命名为 NSTextFieldSubClass
,那么我同意@MichaelDautermann 的观点,你永远不应该用 NS
前缀命名 classes;这既令人困惑又自找麻烦,因为据您所知,Apple 有一个私有 subclass 正是这个名字。 Class 以 NS
开头的名称由 Apple 保留。
可能是你认为在你显然命名为 NSTextFieldSubClass
的变量中的对象根本不是你的 subclass 的实例,或者已经已释放(并且可能被同一地址的新对象替换)或某些此类问题,这就是它不响应选择器的原因。您可以通过打开 NSZombieEnabled
、在调试器中检查它、添加它的 NSLog
(可能在您的 subclass 中添加 -description
方法)来调查此问题,或者许多其他技术。
这一切都非常模糊,但问题是模糊的。您至少需要 post 子程序的代码 class、实例化子程序的代码 class 以及崩溃行周围的代码,以获得更具体的帮助.我们无法读懂您的想法,错误的根源很可能就在其中一个地方。
我有一个 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:
选择器被发送到无法识别该选择器的对象。会发生什么会导致这种情况?弄清楚这样的事情需要批判性思维和侦探工作。这里有一些想法。
-setLineBreakMode:
好像并没有真正被NSTextField
实现;据我所知,它是NSCell
和NSMutableParagraphStyle
的方法。如果您有NSTextField
(或它的子 class),您通常会调用[[myTextField cell] setLineBreakMode:...]
,但您的代码片段并不表示您正在这样做。所以除非你在你的 subclass 中实现了这个方法——你没有声明你做了——这可能是崩溃的原因。也许您没有在 Mac 上看到崩溃,因为无论出于何种原因,此代码路径都没有受到影响?或者也许 Apple 在 Yosemite 中私下实现了此方法,但在 Mavericks 中没有实现?谁知道。您是否在该行收到来自编译器的警告,说该对象不响应该选择器?不要忽略编译器警告。您 post 编辑的代码看起来像是在 class 对象上调用
setLineBreakMode:
,而不是在 class 的实例上;通常 classes 以大写字母开头,而实例以小写字母开头。像这样遵守编码约定可以减少每个人的困惑。如果你的 subclass 真的被命名为NSTextFieldSubClass
,那么我同意@MichaelDautermann 的观点,你永远不应该用NS
前缀命名 classes;这既令人困惑又自找麻烦,因为据您所知,Apple 有一个私有 subclass 正是这个名字。 Class 以NS
开头的名称由 Apple 保留。可能是你认为在你显然命名为
NSTextFieldSubClass
的变量中的对象根本不是你的 subclass 的实例,或者已经已释放(并且可能被同一地址的新对象替换)或某些此类问题,这就是它不响应选择器的原因。您可以通过打开NSZombieEnabled
、在调试器中检查它、添加它的NSLog
(可能在您的 subclass 中添加-description
方法)来调查此问题,或者许多其他技术。
这一切都非常模糊,但问题是模糊的。您至少需要 post 子程序的代码 class、实例化子程序的代码 class 以及崩溃行周围的代码,以获得更具体的帮助.我们无法读懂您的想法,错误的根源很可能就在其中一个地方。