Ios 如何使Swift协议符合特定类别?

Ios 如何使Swift协议符合特定类别?,ios,swift,class,protocols,Ios,Swift,Class,Protocols,我用Swift写了一份协议: protocol FooDelegate{ titleImage:UIImage? {get} } 我想确保符合它的类必须是UITableViewController类型 换言之: // ViewController conform FooDelegate is OK,Because ViewController // is inherit from UITableViewController! class ViewController:UITableV

我用Swift写了一份协议:

protocol FooDelegate{
    titleImage:UIImage? {get}
}
我想确保符合它的类必须是UITableViewController类型

换言之:

// ViewController conform FooDelegate is OK,Because ViewController 
// is inherit from UITableViewController!
class ViewController:UITableViewController,FooDelegate /* compile ok */{

}

// OtherVC is failed to conform FooDelegate,Because it is not inherit
// from UITableViewController.
class OtherVC:UIViewController,FooDelegate /* will compile error */{

}
怎么做

我将FooDelegate的定义更改为:

protocol FooDelegate where Self:UITableViewController {
    var titleImage:UIImage? {get}
}
但它似乎不起作用

*固定零件*: 使用Self:UITableViewController正常

但当我在编译时写下以下内容是错误的:

class StubClass{
    var delegate:FooDelegate!

    func invoke(){
        let idxSet = ...
        delegate.tableView.reloadSections(idxSet, with: .none) //Error:Value of type 'FooDelegate' has no member 'tableView'
    }
}
请看上面的那行错误。委托中没有任何tableView属性吗?委托符合FooDelegate,并且FooDelegate使Self:UITableViewController,并且UITableViewController必须具有tableView属性

这里怎么了???谢谢:)

试试这个:

protocol FooDelegate: class where Self: UITableViewController {
    // code
}
如果您希望某些扩展可以通过
UITableViewController
访问:

protocol FooDelegate {
    // code
}

extension FooDelegate where Self: UITableViewController {
    // code
}
试试这个:

protocol FooDelegate: class where Self: UITableViewController {
    // code
}
如果您希望某些扩展可以通过
UITableViewController
访问:

protocol FooDelegate {
    // code
}

extension FooDelegate where Self: UITableViewController {
    // code
}

由于
tableView
属性对协议声明不可见,您只需在协议中添加
tableView
属性。大概是这样的:

@objc protocol FooDelegate where Self: UITableViewController {
    var tableView: UITableView { get }
}

class SimpleTableView: UITableViewController, FooDelegate {

}

let delegate: FooDelegate? = SimpleTableView()

delegate?.tableView.reloadData()

请记住在协议声明中添加
@objc

由于
tableView
属性对协议声明不可见,您只需在协议中添加
tableView
属性即可。大概是这样的:

@objc protocol FooDelegate where Self: UITableViewController {
    var tableView: UITableView { get }
}

class SimpleTableView: UITableViewController, FooDelegate {

}

let delegate: FooDelegate? = SimpleTableView()

delegate?.tableView.reloadData()

请记住在协议声明中添加
@objc

您使用的是哪个版本的Swift?您正在寻找的功能是最近添加的(我相信是4.1)。您的
Self:UITableViewController
应该可以工作。我使用4.1,但它不工作!有什么问题吗?好的,我的错误!!!使用Self:UITableViewController正在工作!!!但是在使用它的地方还有其他错误!请参阅上面的“修复部分”…您使用的是什么版本的Swift?您正在寻找的功能是最近添加的(我相信是4.1)。您的
Self:UITableViewController
应该可以工作。我使用4.1,但它不工作!有什么问题吗?好的,我的错误!!!使用Self:UITableViewController正在工作!!!但是在使用它的地方还有其他错误!请看上面的“修复部分”…谢谢!我知道在FooDelegate中添加tableView属性正在工作。。。,我只是不明白为什么不能智能地推断委托中有一个tableView属性…@hopy我认为通过使用条件一致性,我们可以访问协议或协议扩展中的属性和方法,但我们不能使用协议引用来访问它们以维护类的抽象。@hopy如果我们有要提供对某些属性或方法的访问,我们必须在协议中声明它。正确;编译器中当前级别的类型推断允许它在一致性点强制继承(即,它可以检查类是否实际继承),但它不会将此信息嵌入协议中。这就是为什么它是
协议P,其中Self:C
而不是
协议P:C
。该协议(目前)不是该类的子类型(事实上可能是间接框)。我现在明白了,谢谢!我知道在FooDelegate中添加tableView属性正在工作。。。,我只是不明白为什么不能智能地推断委托中有一个tableView属性…@hopy我认为通过使用条件一致性,我们可以访问协议或协议扩展中的属性和方法,但我们不能使用协议引用来访问它们以维护类的抽象。@hopy如果我们有要提供对某些属性或方法的访问,我们必须在协议中声明它。正确;编译器中当前级别的类型推断允许它在一致性点强制继承(即,它可以检查类是否实际继承),但它不会将此信息嵌入协议中。这就是为什么它是
协议P,其中Self:C
而不是
协议P:C
。该协议(目前)不是该类的子类型(事实上可能是间接框)。我现在理解了,谢谢