我正在尝试实现一个简单的多委托情况:
protocol Subscribable: class {
associatedtype Subscriber: AnyObject
var subscribers: NSHashTable<Subscriber> { get }
}
protocol ControllerSubscriber: class {
func controllerDidSomething()
}
class Controller: Subscribable {
typealias Subscriber = ControllerSubscriber
var subscribers = NSHashTable<Subscriber>.weakObjects() // Error
}
Run Code Online (Sandbox Code Playgroud)
错误:不支持使用'ControllerSubscriber'作为符合协议'AnyObject'的具体类型.
我的问题是:
当然,我该如何解决这个问题?从实际的解决方案而不是解决方案.
我很难理解Swift的泛型系统.我似乎经常遇到这样看似简单的情况.我只是想把一个符合协议的东西放到另一个东西:(.我想知道我的想法出错了所以我可以解决它,而不必再看到这些错误.
有这个相关的问题,但请注意答案只给出解决方法,没有解释或解决方案.
我正在尝试通过符合Encodable协议的编码模型获取数据.但它无法encode像下面的代码那样调用func :
// MARK: - Demo2
class TestClass2: NSObject, Encodable {
var x = 1
var y = 2
}
var dataSource2: Encodable?
dataSource2 = TestClass2()
// error: `Cannot invoke 'encode' with an argument list of type '(Encodable)'`
let _ = try JSONEncoder().encode(dataSource2!)
//func encode<T>(_ value: T) throws -> Data where T : Encodable
Run Code Online (Sandbox Code Playgroud)
但在另一个演示中,它运作良好,为什么?
// MARK: - Demo1
protocol TestProtocol {
func test()
}
class TestClass1: NSObject, TestProtocol {
func test() {
print("1")
}
var …Run Code Online (Sandbox Code Playgroud) 我无法使用以下代码:
@objc protocol Child { }
@objc protocol Parent {
var child: Child { get }
}
class ChildImpl: Child {
func doSomething() { }
}
class ParentImpl: Parent {
let child = ChildImpl()
// this would solve the problem, however can't access the ChildImpl members
// that are not part of the protocol
// let child: Child = ChildImpl()
// as well as this, however maintaining two properties is an ugly hack
// var child: Child { return childImpl …Run Code Online (Sandbox Code Playgroud) 我想写一个弱属性要求的协议.符合它的类必须能够为此属性指定任何类型.此外,我不想指定实际类型,因此它应该是使用某些协议指定的类型.此代码显示了我对非弱属性的想法:
protocol ObjectProtocol: class {
typealias PropertyType
var property: PropertyType {get set}
}
protocol FirstPropertyProtocol: class {}
protocol SecondPropertyProtocol: class {}
class FirstObjectImpl: ObjectProtocol {
var property: FirstPropertyProtocol?
}
class SecondObjectImpl: ObjectProtocol {
var property: SecondPropertyProtocol?
}
Run Code Online (Sandbox Code Playgroud)
它按预期工作.
我试图为弱属性做同样的事情:
protocol ObjectProtocol: class {
typealias WeakPropertyType: AnyObject //must be a class type
weak var weakProperty: WeakPropertyType? {get set}
}
protocol WeakPropertyProtocol: class {}
class ObjectImpl: ObjectProtocol {
weak var weakProperty: WeakPropertyProtocol?
}
Run Code Online (Sandbox Code Playgroud)
我收到了编译错误:
类型'ObjectImpl'不符合协议'ObjectProtocol'
有什么方法可以让我的工作吗?
我尝试使用通用协议实现面向对象的代码.可以说我有两个协议
protocol Executable: class {
func execute()
}
protocol Dockable: class {
associatedtype T
func dock(object: T)
}
Run Code Online (Sandbox Code Playgroud)
我为Executable实现了一个装饰器:
final class DockableExecutable: Executable, Dockable {
typealias T = Executable
private let decorated: Executable
private var docked: Executable?
init(_ decorated: Executable) {
self.decorated = decorated
}
// from Executable
func execute() {
decorated.execute()
docked?.execute()
}
// from Dockable
func dock(object: Executable) {
docked = object
}
}
Run Code Online (Sandbox Code Playgroud)
现在我不想在类这样的类中使用它:
final class MyViewController: UIViewController {
init(save: Executable, uiUpdateConnector: Dockable<Executable>) {}
}
Run Code Online (Sandbox Code Playgroud)
但这是不可能的,因为协议本身不是通用的,只是功能.编译器告诉我:
不能专门化非泛型类型'可停靠' …
有两种情况让我在使用Xcode 7.1开发swift 2.2时感到困惑,请看下面的例子,谢谢
首先,当导入Foundation时,我声明了一个testArray,它包含两个项目,一个Integer类型1和一个String类型"hello",我的问题是为什么Swift类型推断testArray到Array(NSObject)而不是Array(Any)
import Foundation
let testArray = [1, "hello"]
print(testArray.dynamicType) //testArray is Array<NSObject>
Run Code Online (Sandbox Code Playgroud)
其次,当我删除import Foundation时,下面的代码无法编译,错误信息是"表达式的类型没有更多内容",我的问题是为什么Swift在这种情况下没有对Array(Any)进行类型推断,谢谢求助
let testArray2 = [2, "world"]
print(testArray2)
//can't compile, error message = "Type of expression is ambiguous without more content"
Run Code Online (Sandbox Code Playgroud) 我在调用数组方法时遇到问题index(of:).
MyClass继承UIViewController并符合MyDelegate协议.
//self.viewControllers: [(UIViewController & MyDelegate)]
guard let myController = viewController as? MyClass,
let index = self.viewControllers.index(of: myController) else {return}
Run Code Online (Sandbox Code Playgroud)
然后我得到错误:
无法使用类型'(of:(UIViewController&MyDelegate))'的参数列表调用'index'
如何解决这个问题,是否有比index(of:)在扩展中实现更好的解决方案?
extension Array where Element == (UIViewController & MyDelegate) {
func index(of: Element) -> Int? {
for i in 0..<self.count {
if self[i] == of {
return i
}
}
return nil
}
}
Run Code Online (Sandbox Code Playgroud) 我使用Swift遇到了一个奇怪的错误,但我似乎无法找到问题.我认为不应该抛出错误,我已经在操场上用下面的代码验证了这个问题.
protocol Sortable {
}
protocol ItemA: Sortable {
}
func sortItems<T: Sortable>(items: [T]) -> [T] {
// do the sorting here
return items
}
let list: [ItemA] = []
sortItems(items: list)
Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个WeakReference可以放入数组的泛型类型(并最终创建一个泛型弱数组类型)。
到目前为止一切顺利,但以下代码:
class WeakReference<ElementType: AnyObject> {
weak var element: ElementType?
init(_ element: ElementType) {
self.element = element
}
}
protocol Element: AnyObject {}
class WeakElementHolder {
var weakElements: [WeakReference<Element>] = []
}
Run Code Online (Sandbox Code Playgroud)
产生这个编译器错误:
WeakReference.swift:12:21: error: 'WeakReference' requires that 'Element' be a class type
var weakElements: [WeakReference<Element>] = []
^
WeakReference.swift:1:7: note: requirement specified as 'ElementType' : 'AnyObject' [with ElementType = Element]
class WeakReference<ElementType: AnyObject> {
^
Run Code Online (Sandbox Code Playgroud)
这很奇怪,因为协议肯定需要一个类 ( AnyObject)。
奇怪的是,如果我省略泛型,一切正常:
protocol Element: AnyObject {}
class WeakElementReference { …Run Code Online (Sandbox Code Playgroud) 我试图弄清楚如何定义一个采用以下两个参数的函数:
例如,给定
protocol P { }
class C : P { } // Class, conforming to P
class D { } // Class, not conforming to P
struct E: P { } // Struct, conforming to P
Run Code Online (Sandbox Code Playgroud)
这应该编译:
register(P.self, obj: C()) // (1)
Run Code Online (Sandbox Code Playgroud)
但这些不应该编译:
register(P.self, obj: D()) // (2) D does not conform to P
register(P.self, obj: E()) // (3) E is not a class
Run Code Online (Sandbox Code Playgroud)
如果我们放弃第二个参数是类实例的条件,这很容易:
func register<T>(proto: T.Type, obj: T) {
// ... …Run Code Online (Sandbox Code Playgroud)