【问题标题】:How set a method as argument of class method in objective-c如何在objective-c中将方法设置为类方法的参数
【发布时间】:2012-10-15 14:37:10
【问题描述】:

我在编写一个类方法时遇到问题,它有一个方法有参数。

函数在类“SystemClass.m/h”中

//JSON CALL
+(void)callLink:(NSString*)url toFunction:(SEL)method withVars:(NSMutableArray*)arguments {
    if([self checkConnection])
    {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSData *datas = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
            [arguments addObject:datas];
            [self performSelectorOnMainThread:@selector(method:) withObject:arguments waitUntilDone:YES];
        });
    }else{
        [self alertThis:@"There is no connection" with:nil];
    }
}

该函数的作用是调用一个 JSON url,并将数据提供给一个方法

我是这样使用的:

[SystemClass callLink:@"http://www.mywebsite.com/call.php" toFunction:@selector(fetchedInfo:) withVars:nil];

但它会像这样崩溃:

由于未捕获的异常而终止应用程序 'NSInvalidArgumentException',原因:'+[SystemClass 方法:]: 无法识别的选择器发送到类 0x92d50'

你能帮帮我吗?无论如何,我正在努力寻找解决方案!

谢谢,亚历克斯

【问题讨论】:

  • 这与 Xcode 无关。重新标记。
  • 现在更好的解决方案是使用块而不是选择器、目标和参数

标签: iphone ios class methods


【解决方案1】:

在您的 callLink 方法中,您已经给出了一个选择器作为参数(它是称为“方法”的参数)。此外,您还需要添加一个参数,因为“方法”参数应该从实现此方法的对象中调用(在您给我们的示例中,应用程序将尝试从 SystemClass 调用名为“方法”的方法,当您打电话:

[self performSelectorOnMainThread:method withObject:arguments waitUntilDone:YES];

这里的 self 是 SystemClass,而 SystemClass 中似乎不存在这样的方法,这就是它崩溃的原因)。所以在参数中添加一个目标(一个 id 对象):

+(void)callLink:(NSString*)url forTarget:(id) target toFunction:(SEL)method withVars:(NSMutableArray*)arguments;

所以对于以下行,您应该只给出选择器并在目标对象上调用此选择器:

[target performSelectorOnMainThread:method withObject:arguments waitUntilDone:YES];

而不是:

[self performSelectorOnMainThread:@selector(method:) withObject:arguments waitUntilDone:YES];

改进:

在调用选择器之前,您应该检查目标是否响应选择器做类似的事情(它会防止您的应用程序崩溃)。而不是这样做:

[target performSelectorOnMainThread:method withObject:arguments waitUntilDone:YES];

这样做:

if([target respondsToSelector:method])
{
  [target performSelectorOnMainThread:method withObject:arguments waitUntilDone:YES];
}
else
{
  //The target do not respond to method so you can inform the user, or call a NSLog()...
}

【讨论】:

  • 我改变了,但它仍然继续崩溃! (我不知道是否清楚:我有一个包含“SystemClass.h”的“ViewController.m”,我想在 ViewController 中调用[SystemClass callLink..]
  • 如果你在一个对象上调用 performSelectorOnMainThread,选择器应该存在于这个对象中。我将编辑我的答案。
  • 好的(即一个 UIViewController?)我像 NSObject 一样传递它,并把它而不是“self”?
  • 不,只是传递一个 id 作为参数。 id 将是您想要的任何对象。查看我的编辑;)
  • 不客气。我已经添加了一些改进,你应该看看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-23
  • 1970-01-01
  • 2020-04-12
  • 2020-09-16
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多