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

Objective-C类与Swift协议成员命名冲突,如何同时兼容?

解决NSTextFieldCell与NSTextAttachmentCellProtocol的cellSize选择器冲突问题

这个冲突的核心是Objective-C选择器重复:NSTextFieldCell的父类NSCell里,cellSize属性的getter选择器是cellSize;而NSTextAttachmentCellProtocol要求实现的cellSize()方法,其Objective-C选择器也是cellSize,两者桥接时就会撞车。

最简单的解决方法

直接删掉单独的func cellSize() -> NSSize实现,只保留重写的cellSize属性就行。因为在Objective-C里,属性的getter本质就是一个方法,你重写的cellSize属性的getter会自动提供-cellSize方法,完全能满足NSTextAttachmentCellProtocol的要求。

修改后的代码:

class NewCell: NSTextFieldCell, NSTextAttachmentCellProtocol {
    override var cellSize: NSSize {
        return NSSize(width: 40, height: 24)
    }

    // 别忘了实现协议的其他必要方法,比如绘制方法:
    func draw(withFrame frame: NSRect, in controlView: NSView?) {
        // 这里写你的绘制逻辑
    }
    
    // 其他协议方法按需实现...
}

特殊场景的备选方案(不推荐)

如果确实需要给协议方法和属性设置不同的逻辑(这种情况很少见),可以通过@objc重命名选择器,同时手动处理方法响应:

class NewCell: NSTextFieldCell, NSTextAttachmentCellProtocol {
    override var cellSize: NSSize {
        return NSSize(width: 40, height: 24)
    }

    // 给协议方法指定自定义选择器
    @objc(textAttachmentCellSize)
    func cellSize() -> NSSize {
        return NSSize(width: 50, height: 30)
    }
    
    // 手动处理协议方法的选择器响应
    override func responds(to aSelector: Selector!) -> Bool {
        if aSelector == #selector(cellSize) {
            return true
        }
        return super.responds(to: aSelector)
    }
    
    override func perform(_ aSelector: Selector!, with object: Any?) -> Any? {
        if aSelector == #selector(cellSize) {
            return cellSize()
        }
        return super.perform(aSelector, with: object)
    }
    
    // 其他协议方法...
}

这种方式繁琐且容易引入兼容性问题,非必要别用。

内容的提问来源于stack exchange,提问作者Peter R

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 22:35:25