无法声明具有内部要求的 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.
我正在编写一个媒体播放器应用程序,并创建了我自己的框架来管理所有播放器功能。在这个框架中,我有一个名为 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.