根据我到目前为止所了解到的:在object中,您可以向任何对象发送任何消息。如果对象确实实现了正确的方法,那么它将被执行,否则什么都不会发生。这是因为在发送消息之前,Objective将执行respondsToSelector.。
我希望到目前为止我是对的。
我做了一个小程序,用于测试每次移动滑块时调用动作的位置。此外,为了进行测试,我将发送方设置为NSButton,但实际上它是一个NSSlider。现在我问对象它是否会响应setAlternateTitle.而一个NSButton就行,而NSSlider不行。如果我运行代码并亲自执行respondsToSelector,它将告诉我对象不会响应该选择器。如果我测试像intValue这样的其他东西,它就会响应。所以到目前为止我的代码还不错。
- (IBAction)sliderDidMove:(id)sender
{
NSButton *slider = sender;
BOOL responds =
[slider respondsToSelector:@selector(setAlternateTitle)];
if(responds == YES)
{
NSLog(@"YES");
}
else
{
NSLog(@"NO");
}
[slider setAlternateTitle:@"Hello World"];
}但是当我实际发送setAlternateTitle消息时,程序会崩溃,我不太清楚原因。在发送消息之前,它不应该做一个respondsToSelector吗?
发布于 2011-01-01 15:45:45
首先,如mvds所说,方法的名称(其选择器)包括所有子部分和冒号字符。
第二,运行时不调用方法-respondsToSelector:,它通常由用户调用(您或API希望知道委托是否响应协议的可选方法)。
当您向对象发送消息时,运行时将在对象的类中(通过对象的isa指针)查找方法的实现。这相当于发送-respondsToSelector:,尽管消息本身没有发送。如果方法的实现在类中或其超类中找到,则会使用传入的所有参数调用该方法。
如果没有,则运行时给消息第二次执行的机会。它首先将消息+ (BOOL)resolveInstanceMethod:(SEL)name发送到对象的类:该方法允许您在运行时将方法添加到类中:如果此消息返回是,则意味着它可以重新分派消息。
如果不给消息第三次执行的机会,它会与选择器一起发送- (id)forwardingTargetForSelector:(SEL)aSelector,该方法可以返回另一个对象,该对象可以代表实际的接收方响应选择器,如果返回的对象可以响应,则执行该方法并返回该值,就好像它是由原始消息返回的一样。(注意:这可以从OSX10.6或iOS 4开始。)
如果返回的对象为零或自(以避免无限循环),运行时将给消息第四次执行方法…的机会。它发送消息- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector以获取方法签名,以构建调用。如果提供了一个调用,则通过消息- (void)forwardInvocation:(NSInvocation *)anInvocation发送调用。在此方法中,您可以解析调用并构建其他消息,以任意方式发送到其他目标,然后可以设置调用…的返回值。该值将充当原始消息的返回值。
最后,如果对象没有返回任何方法签名,那么运行时将消息- (void)doesNotRecognizeSelector:(SEL)aSelector发送给您的对象,则NSObject类中该方法的实现将抛出一个异常。
发布于 2011-01-01 15:19:01
首先,selector不仅是消息的“名称”,还包括以下内容,即参数及其名称。
因此,某些-(void)setAlternateTitle:(NSString*)str的正确选择器应该是
@selector(setAlternateTitle:)与:
至于您的问题:如果类respondsToSelector()和您执行该选择器,您不应该在发送未知的选择器时崩溃。您在调试窗口中看到什么样的崩溃日志?
(ps. )为什么不将[slider setAlternateTitle:...]包含在if ( responds ) { ... }条件块中?)
发布于 2011-01-01 15:23:09
“这是因为在消息发送之前,Objective将执行respondsToSelector。
我想这不对。如果对象不响应选择器,它将在运行时崩溃。系统没有自动检查。如果运行时系统进行了检查,那么我们就不应该得到“未识别的选择器被发送到实例”异常。
如果我错了,请让我改正。
编辑:这不是一个直接的崩溃,但默认的结果是进程将被终止。整个序列已经在评论和其他回答中解释过了,所以我不打算再写了。
https://stackoverflow.com/questions/4574465
复制相似问题