1

我创建了一个类SYFactory,其中包含用于组装对象(主要是UIViews 和UIControls)的各种类方法。这些类方法由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对象试图在响应者链中找到一个它认为最有可能回答该消息的对象。该对象属于 class SYFixedMarginView,因此出现错误消息:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'-[SYFixedMarginView showTheVideoPane:]: unrecognized selector sent to instance 0x1f877d60'

所以修复很简单。__strong除了for循环中的局部变量之外,我还将视图控制器分配给了一个属性。

希望其他人不要落入同样的陷阱。

4

0 回答 0