UIButtonTypeDetailDisclosure : 无法识别的选择器发送到实例

Posted

技术标签:

【中文标题】UIButtonTypeDetailDisclosure : 无法识别的选择器发送到实例【英文标题】:UIButtonTypeDetailDisclosure : unrecognised selector sent to instance 【发布时间】:2013-02-11 22:43:48 【问题描述】:

我有一个自定义按钮类:

CustomButton.h 文件:

@interface CustomButton : UIButton
@property (nonatomic, retain) NSString* info;
@end

CustomButton.m 文件:

#import "CustomButton.h"

@implementation CustomButton

@synthesize info;

- (id)initWithFrame:(CGRect)frame

    self = [super initWithFrame:frame];
    if (self) 
        // Initialization code
    
    return self;


@end

在我的主视图控制器中:

CustomButton* btn = [CustomButton buttonWithType:UIButtonTypeDetailDisclosure];

[btn setInfo:@"foobar"];
NSLog(@"%@", [btn info]);

[self.view addSubview:btn];

如果它只是一个简单的按钮 ([CustomButton new]),我不会收到任何错误。但是如果我选择buttonWithType:UIButtonTypeDetailDisclosure 我会收到这个错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', 
reason: '-[UIButton setInfo:]: unrecognized selector sent to instance 0x753c8c0'

为什么会这样?

【问题讨论】:

【参考方案1】:

只要UIButton 不提供initWithType: 方法 - 您就不能子类化“键入”按钮。您也不能为库类创建extension。 将某些东西“附加”到预定义对象的唯一方法是使用associated objects:

#import <objc/runtime.h>
    
UIButton* btn = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
NSString* info = @"foobar";
objc_setAssociatedObject(btn, "info", info, OBJC_ASSOCIATION_RETAIN);
//Later somewhere
NSString* btnInfo = (NSString*)objc_getAssociatedObject(btn, "info");

“信息”可以是您喜欢的任何字符串,它只是稍后检索该对象的键。 OBJC_ASSOCIATION_RETAIN 表示在调用btn 对象的dealloc: 之后对象将被保留并自动释放。您可以找到有关该here 的更多详细信息。

解决您的问题的另一种方法是继承 UIButton,添加您的 info 属性并通过使用 setImage:forState: 方法设置自定义图像使其看起来像披露按钮。

通常,将一些数据与标准 UI 控件耦合是不良架构的标志。也许您会后退一步,尝试找到其他方法将该字符串传递到您需要使用它的地方?

【讨论】:

【参考方案2】:

您调用的buttonWithType: 方法来自UIButton,而不是您的CustomButton 类。 buttonWithType: 的返回值为UIButton。即使您将其分配给CustomButton 类型的变量,它仍然是UIButton 对象。由于UIButton 没有info 属性或setInfo: 方法,因此您会看到您看到的错误。

【讨论】:

那么如何创建 buttonWithType 并添加其他属性/功能? 这是个好问题。我刚刚回答了你为什么会遇到这个问题。我不知道一个好的解决方案。除非您可以使用标准的 initWithFrame: 方法来创建它,否则覆盖 UIButton 会很棘手。

以上是关于UIButtonTypeDetailDisclosure : 无法识别的选择器发送到实例的主要内容,如果未能解决你的问题,请参考以下文章