我正在为iOS 7制作程序,但因为我在几个视图中使用了几乎相同的方法,所以我想创建一个覆盖大部分方法的公共类,并使用回调方法进行画龙点睛,这是每个视图分开。我在视图中有以下代码:
// On top of the view .m
#import "Common.h"
// Method which will be called.
-(void)doSomething
{
NSLog(@"doSomething...");
[Common target:self method:@selector(callbackMethod)];
}
// Method I want to be called.
+(void)callbackMethod
{
NSLog(@"Should come here...");
}
Common.h如下:
#import <Foundation/Foundation.h>
@interface Common : NSObject
+(void)target:(Class)object method:(SEL)selector;
@end
Common.m如下:
+(void)target:(Class)object method:(SEL)selector
{
NSLog(@"target...");
if ([object respondsToSelector:@selector(selector)])
{
[object performSelector:@selector(selector)];
} else {
NSLog(@"%@", object);
}
}
在运行时,它只输出: 做一点事..., 目标..., &lt; ParentViewController:0x8d24bb0&gt;
这里的问题是调用回调方法。程序将到达Common.m中的方法,但无法从父级调用该方法。
答案 0 :(得分:2)
问题在于
@selector(selector)
搜索名为“selector”的方法。 @selector()
检索名称包含在括号内的选择器。
你想要的是使用传入的选择器,而不是检索不同的选择器。你可以像传入任何其他变量一样将它传递给选择器方法:
+(void)target:(Class)object method:(SEL)selector
{
NSLog(@"target...");
if ([object respondsToSelector:selector])
{
[object performSelector:selector];
} else {
NSLog(@"%@", object);
}
}
使用ARC时,这会引发警告,因为ARC系统无法分辨出发生了什么。要通知编译器您故意调用performSelector:
并且确定没有泄漏,您可以关闭这一行的警告。 只有在您完全确定没有泄漏时才这样做。
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[object performSelector:selector];
#pragma clang diagnostic pop
最后,让我们看一下您的选择callbackMethod
:
+(void)callbackMethod
{
NSLog(@"Should come here...");
}
这是一个类方法,而不是实例方法,因此您的类的实例不响应选择器,而类本身也是如此。将它从类方法更改为实例方法(通过将'+'替换为' - ')将解决此问题:
-(void)callbackMethod
{
NSLog(@"Should come here...");
}