オブジェクト (主にと)SYFactoryを組み立てるために使用されるさまざまなクラス メソッドを含むクラスを作成しました。これらのクラス メソッドは、オブジェクト (より正確には、と呼ばれるサブクラスのインスタンス) によって呼び出されます。UIViewUIControlUIViewControllerUIViewControllerSYViewController
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
他の人が同じ罠に陥らないことを願っています。