You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用JSQMessageViewController子类的selector报错,父类已实现该方法,为何?

分析与解决方案

这个问题看起来有点绕,但核心其实和Objective-C的方法可见性、继承逻辑以及JSQMessageViewController的内部实现细节有关。我来帮你拆解一下:

为什么MessagesVc不用重写就能正常调用scrollViewDidScroll:?

JSQMessageViewController本身就是UIScrollViewDelegate的实现者,它内部已经处理了滚动事件。当你子类化它得到MessagesVc时,MessagesVc的scrollView的delegate默认就是自己,由于继承关系,滚动事件触发时,消息会沿着继承链向上查找,最终找到JSQMessageViewController的scrollViewDidScroll:实现——这个过程不需要你在子类里重写,系统会自动完成消息转发。

为什么JSQBaseViewController重写并调用super.scrollViewDidScroll:会报错?

大概率是以下几个原因之一:

1. 父类的scrollViewDidScroll:方法未在公开头文件中显式声明

虽然JSQMessageViewController遵守UIScrollViewDelegate协议,但有些第三方库会把协议方法的实现放在.m文件里,不在公开头文件中重复声明这个方法。在Objective-C中,如果子类调用super的某个方法,但该方法在父类公开头文件中找不到声明,编译器会对方法签名做隐式推断,一旦推断错误,就会导致运行时触发unrecognized selector sent to instance错误。

2. 重写的方法签名有误

检查JSQBaseViewController里的scrollViewDidScroll:是不是写错了:

  • 有没有漏掉参数(UIScrollView *)scrollView?
  • 方法名拼写错误?比如写成scrollViewDidScrolled:或者少了末尾的冒号?
  • 返回值是不是void?

如果方法签名和父类的不匹配,调用super时自然找不到对应的方法。

3. 调用selector时的语法错误

如果是你手动调用这个selector(比如用performSelector:),有没有把selector写成@selector(scrollViewDidScroll)而不是@selector(scrollViewDidScroll:)?少了冒号意味着这是无参方法,和父类的有参方法完全是两个不同的selector,肯定会报错。

怎么解决?

针对不同的原因,对应解决方案:

  • 如果是头文件声明问题:你可以在JSQBaseViewController.m的顶部类扩展中,显式声明这个方法,告诉编译器父类有这个方法:

    // 在JSQBaseViewController.m的顶部
    @interface JSQMessageViewController ()
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView;
    @end
    

    这样编译器就能正确识别父类的方法签名,不会再出现推断错误。

  • 如果是方法签名错误:仔细核对你的重写方法,确保和协议定义的完全一致:

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        [super scrollViewDidScroll:scrollView];
        // 你的自定义逻辑
    }
    
  • 如果是selector调用错误:检查所有调用这个方法的地方,确保selector是@selector(scrollViewDidScroll:)(注意末尾的冒号)。

另外,如果你用的是比较旧版本的JSQMessageViewController,也可以看看官方更新日志,有没有关于这个方法的修改——不过大概率还是前面提到的方法可见性或者签名问题。

内容的提问来源于stack exchange,提问作者Chen Li Yong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:25:17