【问题标题】:Crash when using performSelector: with a SEL passed from another class使用 performSelector 时崩溃:使用从另一个类传递的 SEL
【发布时间】:2012-02-15 19:00:31
【问题描述】:

是否可以将选择器发送到另一个类并让它在另一个类上执行?

这似乎因错误*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[webManager _selector]: unrecognized selector sent to instance 而崩溃。如果这不可能,您会推荐什么替代方案?

方法按执行顺序排列。

//in HomeViewController
-(void)viewDidLoad
{
    WebManager *webManager = [[WebManager alloc] init];
    URLCreator *urlCreator = [[URLCreator alloc] initWithParam:@"default"];
    [webManager load:[urlCreator createURL] withSelector:@selector(testSelector)];
}
//in WebManager, which is also the delegate for the URL it loads when the load method is called...
-(void)load:(NSString*)url withSelector:(SEL)selector
{
    _selector = selector;    
    [self load:url];
}

-(void)load:(NSString*)url{
    NSURLRequest * request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    [connection start];
}

//now the delegate response, ALSO in WebManager
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
    NSLog(@"Connection did finish loading. Parsing the JSON");

    [self getJSONDict:rawData]; //parses the data to a dictionary

    //perform the selector that is requested if there is one included
    if (_selector)
    {
        NSLog(@"Performing selector: %@", NSStringFromSelector(_selector));
        //the selector is called testSelector
        [self performSelector:@selector(_selector)];    
    }
}

- (void)testSelector //also in the WebManager class
{
    NSLog(@"Selector worked!");
}

【问题讨论】:

    标签: objective-c cocoa-touch selector performselector


    【解决方案1】:

    这是你的问题:

    [self performSelector:@selector(_selector)];
    

    SEL 是表示方法名称的类型。 @selector 是一个编译器指令,它将括号内的 文字 转换为 SEL

    但是_selector,你的ivar,已经包含一个SEL。您正在将 text "_selector" 转换为 SEL,然后尝试使用它。由于目标类中不存在带有选择器“_selector”的方法,因此会出现异常。

    将行改为:

    [self performSelector:_selector];
    

    一切都应该是花花公子。这将使用您已经存储在 变量 _selector 中的SEL

    另外,一般来说,请先发布你的真实代码

    【讨论】:

    • 谢谢,但我收到一条警告,指出“PerformSelector 可能导致泄漏。”有没有办法消除这个错误?
    • 供其他人参考...#pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" [self performSelector:_selector]; #pragma clang diagnostic pop
    【解决方案2】:
    [self performSelector:@selector(_selector)];   
    

    上面的代码实际上转换为 [self _selector] 我假设这不是你想要的。您应该将代码更改为

    [self performSelector:_selector];   
    

    【讨论】:

      猜你喜欢
      • 2015-01-26
      • 1970-01-01
      • 1970-01-01
      • 2017-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多