我想做这样的事情,但无法正确使用语法或在网络上的任何地方找到正确的方法来编写它:
protocol JSONDecodeable {
static func withJSON(json: NSDictionary) -> Self?
}
protocol JSONCollectionElement: JSONDecodeable {
static var key: String { get }
}
extension Array: JSONDecodeable where Element: JSONCollectionElement {
static func withJSON(json: NSDictionary) -> Array? {
var array: [Element]?
if let elementJSON = json[Element.key] as? [NSDictionary] {
array = [Element]()
for dict in elementJSON {
if let element = Element.withJSON(dict) {
array?.append(element)
}
}
}
return array
}
}
Run Code Online (Sandbox Code Playgroud)
所以我只想在这个数组的元素符合时才符合Array我的协议.JSONDecodeableJSONCollectionElement
这可能吗?如果是这样,语法是什么?
我发现了一个有趣的行为,似乎是一个bug ...
基于以下文章描述的行为:
https://medium.com/ios-os-x-development/swift-protocol-extension-method-dispatch-6a6bf270ba94
http://nomothetis.svbtle.com/the-ghost-of-swift-bugs-future
当我添加时SomeSuperclass,输出不是我所期望的,而不是直接采用协议.
protocol TheProtocol {
func method1()
}
extension TheProtocol {
func method1() {
print("Called method1 from protocol extension")
}
func method2NotInProtocol() {
print("Called method2NotInProtocol from protocol extension")
}
}
// This is the difference - adding a superclass
class SomeSuperclass: TheProtocol {
}
// It works as expected when it simply adopts TheProtocol, but not when it inherits from a class that adopts the protocol
class MyClass: SomeSuperclass {
func method1() {
print("Called …Run Code Online (Sandbox Code Playgroud) 我建立简单的主题引擎,并希望有一个扩展,它增加了UISwipeGestureRecognizer对UIViewController
这是我的代码:
protocol Themeable {
func themeDidUpdate(currentTheme: Theme) -> Void
}
extension Themeable where Self: UIViewController {
func switchCurrentTheme() {
Theme.switchTheme()
themeDidUpdate(Theme.currentTheme)
}
func addSwitchThemeGestureRecognizer() {
let gestureRecognizer = UISwipeGestureRecognizer(target: self, action:#selector(Self.switchCurrentTheme))
gestureRecognizer.direction = .Down
gestureRecognizer.numberOfTouchesRequired = 2
self.view.addGestureRecognizer(gestureRecognizer)
}
}
Run Code Online (Sandbox Code Playgroud)
当然编译器找不到,#selector(Self.switchCurrentTheme)因为它没有通过@objc指令公开.是否可以将此行为添加到我的扩展程序?
UPDATE: Theme是一个Swift枚举,所以我不能@objc在Themeable协议前添加
在这个例子中使用Swift 2.0中的新扩展协议:
protocol A {
func foo()
}
protocol B {
func foo()
}
extension A {
func foo() { print("A") }
}
extension B {
func foo() { print("B") }
}
class C: A, B {
}
Run Code Online (Sandbox Code Playgroud)
就像" 多重继承 "一样,Python和C++等语言当然可以作为多重继承来处理.让我感到惊讶的是Xcode 7.0 Beta 4给我的两个编译错误:
类型'C'不符合协议'A'
类型'C'不符合协议'B'
但是这个错误没有任何意义,因为错误必须反映协议之间存在的冲突或歧义A以及B关于foo函数的使用或类似的东西.
如果您在上面的代码下面添加以下行:
C().foo()
Run Code Online (Sandbox Code Playgroud)
这启动了我所说的错误类型:
模糊地使用'foo'
我的问题是:
随着Swift 2.0中新增的扩展协议,Apple考虑了对这种" 多重继承 "(类似于C++处理方式)的任何处理,或者根本不允许这样做?
我有一个相当大的应用程序,它有很多集合视图.大多数集合视图都具有相同的数据源和流布局代表(相同的大小,边距等)的实现.我正在尝试创建一个提供UICollectionViewDataSource和UICollectionViewDelegateFlowLayout的默认实现的协议.这是我的代码.
protocol TiledCollectionView{}
extension UICollectionViewDataSource where Self: TiledCollectionView{
//default implementation of the 3 methods to load the data ...
}
extension UICollectionViewDelegateFlowLayout where Self: TiledCollectionView {
//default implementation for layout methods to set default margins etc...
}
class MyViewController: UIViewController, TiledCollectionView, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{
// the rest of the required logic for view controller
// here I Don't implement any CollectionView methods since I have provided the default implementation already
}
Run Code Online (Sandbox Code Playgroud)
问题是,编译器抱怨MyViewController不符合UICollectionViewDataSource.这不应该是这种情况,因为我清楚地说,如果类型是TiledCollectionView,则添加默认实现.
有人可以帮忙吗?
uicollectionview swift swift-extensions swift-protocols protocol-extension
考虑以下:
protocol Foo {
typealias A
func hello() -> A
}
protocol FooBar: Foo {
func hi() -> A
}
extension FooBar {
func hello() -> A {
return hi()
}
}
class FooBarClass: FooBar {
typealias A = String
func hi() -> String {
return "hello world"
}
}
Run Code Online (Sandbox Code Playgroud)
这段代码编译.但是如果我注释掉关联类型的显式定义typealias A = String,那么由于某种原因,swiftc无法推断出类型.
我感觉这与两个共享相同关联类型但没有直接断言的协议有关,例如,类型参数化(可能关联类型不够强大/不够成熟?),这使得类型推断模糊不清.
我不确定这是否是该语言的错误/不成熟,或者可能,我错过了协议扩展中的一些细微差别,这恰恰导致了这种行为.
有人可以对此有所了解吗?
我正在尝试CLLocationManagerDelegate通过协议扩展来实现协议要求,但位置管理器在协议扩展中没有看到它并且失败.但是,当移动到类中时,它使用相同的代码.
这是我正在做的事情:
class ViewController: UIViewController, MyLocationProtocol {
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
locationManager.distanceFilter = 1000.0
locationManager.delegate = self
// Below crashes when implementation in protocol extension
locationManager.requestLocation()
}
}
protocol MyLocationProtocol: CLLocationManagerDelegate {
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
}
extension MyLocationProtocol /*where Self: UIViewControll*/ { // Tried using where clause but still no go :(
// Not being triggered by CLLocationManagerDelegate! :(
// Move …Run Code Online (Sandbox Code Playgroud) 我有一个带有associatedType. 我想typealias在协议扩展中为该类型提供一个默认值。这仅适用于从特定类继承的类。
protocol Foo: class {
associatedtype Bar
func fooFunction(bar: Bar)
}
Run Code Online (Sandbox Code Playgroud)
协议扩展:
extension Foo where Self: SomeClass {
typealias Bar = Int
func fooFunction(bar: Int) {
// Implementation
}
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨'Bar' is ambiguous for type lookup in this context. 我也无法在 swift 书中找到任何有用的东西。
我一直在玩协议扩展,我有一个问题.也许我想要实现的目标无法实现.我有这个游乐场:
//: Playground - noun: a place where people can play
import UIKit
protocol ArrayContainer {
typealias T
var array: [T] { get }
}
class MyViewController: UIViewController, ArrayContainer, UITableViewDataSource {
typealias T = String
var array = ["I am", "an Array"]
}
extension UITableViewDataSource where Self: ArrayContainer {
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// …Run Code Online (Sandbox Code Playgroud) 我写了一个扩展名Int如下.
extension Int {
func squared () -> Int {
return self * self
}
}
print(10.squared()) // works
Run Code Online (Sandbox Code Playgroud)
上面的代码有效.现在我想扩展IntegerType协议,以便Int,UInt,Int64等都符合.我的代码如下.
extension IntegerType {
func squared () -> IntegerType { // this line creates error
return self * self
}
}
Run Code Online (Sandbox Code Playgroud)
我收到错误:
协议'IntegerType'只能用作通用约束,因为它具有Self或关联类型要求
我已经看到了这个问题及其视频和这个问题,仍然无法理解.我只知道associatedType在这种情况下有一些Self但是无法连接点.我觉得我对这个Generics问题缺乏了解也是一个原因......
有人可以详细说明这个主题,为什么扩展会产生错误?