2010-11-28 99 views

回答

30

你的问题是,你声明的委托实例变量:

id<SomeProtocol> delegate; 

,对吗?那么,这意味着编译时检查器只会寻找<SomeProtocol>协议中的方法。但是,performSelector:withObject:afterDelay:NSObject上声明。这意味着你应该声明为伊娃:

NSObject<SomeProtocol> * delegate; 

这是说,它必须是一个NSObject符合<SomeProtocol>,而不是符合<SomeProtocol>任何对象。这应该摆脱你的警告,你不必做任何演员。

3

尝试第一投射委托其类的类型,然后调用performSelector:withObject:afterDelay

[(SomeClass *) delegate performSelector:@selector(doStuff:) withObject:myObject afterDelay:2.0]; 

假设你delegateid类型的,你需要告诉实际上对象也从NSObject继承运行(其中定义了performSelector:withObject:afterDelay:方法)将其转换为类的类型。

+1

任何对象将始终从NSObject继承(一切都会,它是一个根类)。我认为你的意思是符合NSObject协议。 – 2010-11-28 03:11:02

+1

@Evan一切都不会*从NSObject继承。而'performSelector:withObject:afterDelay:`在NSObject协议中没有定义,它在`NSObject`类中定义。 – 2010-11-28 03:12:49

+1

铸造破坏封装。如果这是针对代表类型未知的类的情况呢? – 2010-11-28 03:21:01

2

您需要将委托对象转换为您正在使用的实际类以获得方法。查看委托只能显示协议中定义的方法。 performSelector:withObject:不是在协议中定义的方法。

[(CLASS*)delegate performSelector:@selector(doStuff:) withObject:myObject afterDelay:2.0]; 
1
[NSTimer scheduledTimerWithTimeInterval:2 
    target:self 
    selector:@selector(doStuff) 
    userInfo:nil 
    repeats:NO]; 

尝试是假设你只想要一个计时器

3

尽管Dave提出的NSObject *可以工作,但有一种更清晰的替代方式,可以让人们按照预期使用协议 - 您可以让协议本身声明它支持NSObject协议。

NSObject不仅仅是一个实现,而且是一个包含所有performSelector:方法变体的协议。所以,你可以在你的协议只是声明自己支持NSObject的,就像您的任何其他类支持的协议:

@protocol MyProtocol <NSObject> 

,编译器警告将消失(假设你已经进口协议定义)。

请注意,这确实意味着任何声明支持您的协议的人都必须是NSObject或继承很多方法。但是,由于实际考虑,iPhone编程中使用的所有类都是从NSObject派生的,所以这通常不是问题。

编辑:

原来的-performSelector:withObject:afterDelay:不在NSObject的协议(无延迟的有)。因为如果每个人都使用你的协议,如果他们可以使用id来引用一个协议类型,它仍然更好,我仍然会使用一个协议来解决这个问题 - 但是你必须自己声明一个NSObject协议的扩展。因此,在文件的标题中,您可以添加如下内容:

@protocol MyProtocolNSObjectExtras <NSObject> 
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay; 
@end 

@protocol MyProtocol <NSObjectExtras> 
.... 
@end 

然后,您将获得与前面所述相同的所有优点。

相关问题