1

オブジェクト (主にと)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

他の人が同じ罠に陥らないことを願っています。

4

0 に答える 0