无法声明具有内部要求的公共协议扩展

Kai*_*rdt 6 xcode ios swift swift-extensions swift-protocols

我正在编写媒体播放器应用程序,并创建了自己的框架来管理所有播放器功能.在这个框架中,我有一个名为的公共协议PlayerControllerType和一个内部协议_PlayerControllerType.在PlayerControllerType我已经声明了所有方法和属性,这些方法和属性应该可以从框架外部访问.在_PlayerControllerType我已经定义了几个属性,这些属性由PlayerControllerType框架内部实现的具体类型使用.其中一种类型是PlayerController.其声明如下:

public class PlayerController<Item: Equatable>: NSObject, PlayerControllerType, 
_PlayerControllerType, QueueDelegate
Run Code Online (Sandbox Code Playgroud)

现在我想为我的框架中的类提供一些默认实现,它们符合PlayerControllerType和内部_PlayerControllerType,例如:

import Foundation  
import MediaPlayer  

public extension PlayerControllerType where Self: _PlayerControllerType, Item == MPMediaItem, Self.QueueT == Queue<Item>, Self: QueueDelegate {  

    public func setQueue(query query: MPMediaQuery) {  
        queue.items = query.items ?? []  
    }  

}  
Run Code Online (Sandbox Code Playgroud)

这在Xcode 7 Beta 4中按预期工作.昨天我更新到Beta 6并得到了这个错误:"Extensions不能公开,因为它的泛型要求使用内部类型"(也见截图). Xcode中的错误

我发现这个错误很刺激.当然,这延长了我的框架的好处以外没有任何类型,因为它不能访问内部协议_PlayerControllerType,但它是我的框架内的类型的同时实现是非常有用的PlayerControllerType_PlayerControllerType.

这只是Swift编译器中的一个错误,还是预期的行为?非常不幸的是,这不再适用了,因为现在我必须将这些方法放入一个新创建的基类中,用于所有的PlayerControllers.

任何帮助或反馈将非常感谢.

编辑:以下是协议及其扩展的缩写示例:

public protocol PlayerControllerType {
    typealias Item
    var nowPlayingItem: Item {get}
    func play()
}

protocol _PlayerControllerType {
    var nowPlayingItem: Item {get set}
}

public extension PlayerControllerType where Self: _PlayerControllerType {

    /* 
    I want to provide a default implementation of play() for
    all my PlayerControllers in my framework (there is more than one).
    This method needs to be declared public, because it implements a
    requirement of the public protocol PlayerControllerType. 
    But it cannot be implemented here, because this extension 
    has the requirement _PlayerControllerType. It needs this requirement,
    because otherwise it cannot set the nowPlayingItem. I don't want to
    expose the setter of nowPlayingItem.
    I could make a base class for all PlayerControllers, but then I'm
    restricted to this base class because Swift does not support
    multiple inheritance.
    */
    public func play() {
        if nowPlayingItem == nil {
            nowPlayingItem = queue.first
        }
        // Other stuff
    }

}
Run Code Online (Sandbox Code Playgroud)

Kru*_*nal 3

您需要将_PlayerControllerType协议的访问级别声明为“ public ”。

public protocol _PlayerControllerType {
   // some code
}
Run Code Online (Sandbox Code Playgroud)

根据(《Swift 编程语言 - 访问控制》),

公共成员不能定义为具有内部或私有类型,因为该类型可能无法在使用公共变量的所有地方都可用默认情况下,类被声明为内部类,因此您必须添加 public 关键字以使其成为公共类。

成员(类/协议/函数/变量)不能具有比其参数类型和返回类型更高的访问级别,因为该函数可以在其组成类型不可用于周围代码的情况下使用。