オブジェクト (主にと)SYFactory
を組み立てるために使用されるさまざまなクラス メソッドを含むクラスを作成しました。これらのクラス メソッドは、オブジェクト (より正確には、と呼ばれるサブクラスのインスタンス) によって呼び出されます。UIView
UIControl
UIViewController
UIViewController
SYViewController
UIControl
によって作成されたオブジェクトにセレクターを追加しようとしています。SYFactory
ターゲットは のインスタンスとして設定されていますSYViewController
。
したがって、次のSYFactory
とおりです。
+ (UIControl*)replyPaneWithWidthFromParent:(UIView*) parent selectorTarget:(id) target
{
//...
[replyPane addTarget:target
action:@selector(showTheVideoPane:)
forControlEvents:UIControlEventTouchUpInside];
return replyPane;
}
そしてUIViewController
サブクラス(と呼ばれるSYViewController
)で:
@interface SYViewController ()
@property (readonly, nonatomic) IBOutlet UIImageView *pane;
@property (strong, nonatomic) UIControl *videoPane;
//...
@end
@implementation SYViewController
@synthesize videoPane;
//...
- (void)viewDidLoad
{
//...
self.replyPane = [SYFactory replyPaneWithWidthFromParent:self.pane selectorTarget:self];
}
- (void)showTheVideoPane:(id) sender
{
NSLog(@"Selector selected!");
}
//...
@end
UIControl
コードを実行して、作成した をタップしようとすると、unrecognized selector sent to instance
エラーが発生します。SYViewController
でオブジェクトを引数として渡すので、理由はわかりません+replyPaneWithWidthFromParent:parent selectorTarget:target
。
何らかの奇妙な理由で、UIControl
オブジェクトはメッセージがオブジェクトに送信されるべきではないと考え、SYViewController
代わりに別のクラスのオブジェクトに送信しようとします。変ですよね?
助言がありますか?
編集:
それで、質問を投稿した直後に、私は問題が何であるかを理解しました(物事を書き留めることがそれらを熟考するのに役立つというさらに別の証拠です!):
オブジェクトは、ループSYViewController
内のローカル変数で作成されました。for
オブジェクトへのそれ以上の参照がないため、for
ループが終了すると、SYViewController
オブジェクトは ARC によって破棄されました。
存在しないターゲットに直面したUIControl
オブジェクトは、メッセージに応答する可能性が最も高いと思われるオブジェクトをレスポンダ チェーン内で見つけようとしました。そのオブジェクトはクラスSYFixedMarginView
であったため、エラーメッセージは次のとおりです。
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'-[SYFixedMarginView showTheVideoPane:]: unrecognized selector sent to instance 0x1f877d60'
したがって、修正は簡単です。ループ__strong
内のローカル変数に加えて、View Controller をプロパティに割り当てました。for
他の人が同じ罠に陥らないことを願っています。