0

カスタムボタンクラスがあります:

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'

なぜこうなった?

4

2 に答える 2

1

buttonWithType:呼び出しているメソッドは、クラスUIButtonではなく、からのものです。CustomButtonの戻り値はbuttonWithType:ですUIButton。これを型の変数に割り当てても、CustomButtonそれはUIButtonオブジェクトのままです。プロパティまたはメソッドがUIButtonないため、表示されているエラーが発生します。infosetInfo:

于 2013-02-11T23:06:57.450 に答える
1

UIButtonメソッドを提供しないとすぐにinitWithType:、「入力済み」ボタンをサブクラス化することはできません。ライブラリクラスの拡張機能も作成できません。事前定義されたオブジェクトに何かを「アタッチ」する唯一の方法は、関連付けられたオブジェクトを使用することです。

#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");

「info」は任意の文字列にすることができ、後でそのオブジェクトを取得するための単なるキーです。OBJC_ASSOCIATION_RETAINは、オブジェクトが呼び出された後、btnオブジェクトが保持され、自動的に解放されることを意味しますdealloc:。詳細については、こちらをご覧ください。

問題を解決するもう1つの方法は、UIButtonをサブクラス化し、infoプロパティを追加し、メソッドを使用してカスタム画像を設定することにより、開示ボタンのように見せることですsetImage:forState:

一般に、一部のデータを標準のUIコントロールと結合することは、アーキテクチャが悪いことを示しています。たぶん、少し後退して、その文字列を使用する必要がある場所にその文字列を渡す他の方法を見つけようとしますか?

于 2013-02-12T00:31:48.057 に答える