相关疑难解决方法(0)

不支持使用协议作为符合'AnyObject'的具体类型

我正在尝试实现一个简单的多委托情况:

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的泛型系统.我似乎经常遇到这样看似简单的情况.我只是想把一个符合协议的东西放到另一个东西:(.我想知道我的想法出错了所以我可以解决它,而不必再看到这些错误.

这个相关的问题,但请注意答案只给出解决方法,没有解释或解决方案.

generics macos ios swift

10
推荐指数
1
解决办法
1938
查看次数

为什么不能使用协议`Encodable`作为func中的类型

我正在尝试通过符合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)

protocols swift encodable

10
推荐指数
3
解决办法
3194
查看次数

父子协议关系和ObjC可用性

我无法使用以下代码:

@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)

protocols objective-c swift

9
推荐指数
1
解决办法
465
查看次数

具有关联类型的Swift协议中的弱属性要求

我想写一个弱属性要求的协议.符合它的类必须能够为此属性指定任何类型.此外,我不想指定实际类型,因此它应该是使用某些协议指定的类型.此代码显示了我对非弱属性的想法:

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'

有什么方法可以让我的工作吗?

ios swift

8
推荐指数
2
解决办法
4641
查看次数

Swift-Generics:"不能专门化非泛型类型"

我尝试使用通用协议实现面向对象的代码.可以说我有两个协议

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)

但这是不可能的,因为协议本身不是通用的,只是功能.编译器告诉我:

不能专门化非泛型类型'可停靠' …

oop generics swift

8
推荐指数
1
解决办法
7388
查看次数

为什么当在Array中放置多个类型项时,Swift不会对Any进行类型推断

有两种情况让我在使用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)

arrays types type-inference swift anyobject

7
推荐指数
1
解决办法
412
查看次数

Swift 4无法使用类型的参数列表调用'index'

我在调用数组方法时遇到问题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)

arrays swift swift4

7
推荐指数
1
解决办法
3869
查看次数

在参数类型'[ItemA]'中,'ItemA'不符合预期类型'Sortable'

我使用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)

generics swift

7
推荐指数
1
解决办法
75
查看次数

Swift 4.1 中对类绑定协议的弱引用的通用数组

我正在尝试创建一个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)

arrays generics weak-references swift swift-protocols

7
推荐指数
1
解决办法
1526
查看次数

将协议和符合类(!)实例作为参数的函数

我试图弄清楚如何定义一个采用以下两个参数的函数:

  1. 协议.
  2. 符合该协议的(引用类型)的实例.

例如,给定

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)

generics swift swift-protocols

6
推荐指数
1
解决办法
674
查看次数