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

Cannot declare a public protocol extension with internal requirements

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

public class PlayerController<Item: Equatable>: NSObject, PlayerControllerType, 
_PlayerControllerType, QueueDelegate

现在我想为我的框架中的 classes 提供几个默认实现,它们符合 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 ?? []  
    }  

}  

这在 Xcode 7 Beta 4 中按预期工作。昨天我更新到 Beta 6 并收到此错误: "Extensions cannot be declared public because its generic requirement uses an internal type"(另见屏幕截图)。

我觉得这个错误很烦人。当然,我的框架之外的任何类型都不会受益于此扩展,因为它无法访问内部协议 _PlayerControllerType,但它对于我的框架内同时实现 PlayerControllerType_PlayerControllerType 的类型非常有用.

这只是 Swift 编译器中的错误还是预期的行为? 非常不幸的是,这不再起作用了,因为现在我必须将这些方法放入新创建的基础 class 中,用于我所有的 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
    }

}

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

public protocol _PlayerControllerType {
   // some code
}

根据 (The Swift Programming Language - Access Control),

A public members cannot be defined as having an internal or private type, because the type might not be available everywhere that the public variable is used. Classes are declared as internal by default, so you have to add the public keyword to make them public.

A member (class/protocol/function/variable) cannot have a higher access level than its parameter types and return type, because the function could be used in situations where its constituent types are not available to the surrounding code.