【问题标题】:Performing a selector stored in class执行存储在类中的选择器
【发布时间】:2014-01-18 22:53:09
【问题描述】:

我正在使用下面定义的类来保存选择器和选择器。在我想要执行选择器的选择器的 didSelectRow 方法上。但是,当我使用选择器更改行时,我不断收到“无法识别的选择器发送到实例”异常。

我尝试将选择器的声明更改为“SEL *theSelector”,但这并没有带来任何乐趣,因为当调用 performSelector 时 theSelector 为 NULL。

任何修复/想法将不胜感激。提前致谢。

带选择器的类:

@implementation ClassA{
    UIPickerView *thePicker;
    SEL theSelector;
}

-(id)initWithView:(UIView*)theView{
    thePicker = [[UIPickerView alloc] init];
    thePicker.showsSelectionIndicator = YES;
    thePicker.delegate = self;
    thePicker.dataSource = self;
    [theView addSubview:thePicker];

    theSelector = NULL;
}

-(void)setSelector:(SEL)selector{
    theSelector = selector;
}

-(void)performTheSelector{
    if (theSelector != NULL) {
        [self performSelector:theSelector onThread:[NSThread currentThread] withObject:self waitUntilDone:YES];
    }
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:  (NSInteger)component {
    [self performTheSelector];
}

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    return 1;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    return 10;
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
    return @"Some Row";
}

创建 ClassA 实例并设置选择器的类:

@implementation ClassB{
}

-(void)initWithView:(UIView*)theView{
    ClassA *objectA = [ClassA alloc] initWithView:theView]];
    [objectA setSelector:@selector(theSelectorMethod:)];
}

-(IBAction)theSelectorMethod:(id)sender{
    //do something
}

【问题讨论】:

  • 不应声明为SEL *。错误消息中无法识别的选择器是什么?在 ivar 中的 SEL 还是其他?你为什么做这个? (另请注意,您不需要将 ivars 初始化为 0 - 这是由 alloc 完成的。此外,您的 init 需要 return self。)
  • 上线引发异常:[self performSelector:theSelector onThread:[NSThread currentThread] withObject:self waitUntilDone:YES];
  • 但是错误信息的全文是什么?什么是无法识别的选择器本身?
  • 'NSInvalidArgumentException',原因:'-[ClassA theSelectorMethod:]:无法识别的选择器发送到实例 0x8d391b0'

标签: objective-c selector uipickerview


【解决方案1】:

问题是您在ClassA 上调用选择器,但选择器是ClassB 上的一个方法。

通过说[self performSelector:],您实际上是在说“在当前对象上调用此方法” - 但当前对象是ClassA 类型,而theSelectorMethodClassB 的一部分。

您还需要传递对要在其上调用选择器的对象的引用 - setTarget: 或类似的东西。然后,在您的 performTheSelector 方法中,您将改为使用 [objectB performSelector:...]

不过,看看常见的 Objective-C 设计模式 target-actiondelegation - 它们在 Cocoa 中得到了非常广泛的应用,并且都实现了你所追求的那种功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-12
    • 1970-01-01
    • 2013-01-08
    • 1970-01-01
    • 2017-06-21
    • 1970-01-01
    • 1970-01-01
    • 2015-10-05
    相关资源
    最近更新 更多