标签: swift-protocols

替代扩展的方法

我想UIView通过添加一些函数来扩展,并在UIView我想要的任何子类中重写它们。我在苹果文档中发现我无法覆盖扩展(编译器会抱怨),这是有道理的。所以

我需要有人提出以下替代方法:

extension UIView { 
  func hide() { //do almost nothing } 
}

class myLabel: UILabel { 
  override func hide() { 
    //do work on uilabel that can't be done on imgView
  }
}

class myImageView: UIImageView {
 override func hide() { 
    //do work on imgView that can't be done on uilabel
  }
}
Run Code Online (Sandbox Code Playgroud)

我想要这个的原因是,稍后在我的代码中我将面对下面的代码,并且我有很多子类,并且我不想编写太多if-lets尝试将其转换viewmyLabel, myTextView, myImageView... etc

let view = cell.viewWithTag(someTag)
// and I want to write this below without casting …
Run Code Online (Sandbox Code Playgroud)

ios swift swift-extensions swift-protocols

5
推荐指数
1
解决办法
743
查看次数

将 Core Data 类设置为最终类以满足协议“Self”要求

我编写了一个协议,允许将简单链中的对象与前任和后继链接起来。

我尝试将此协议与我的核心数据实体“事件”一起使用,但出现此错误:

错误:

Protocol 'Chainable' requirement 'chain' cannot be satisfied by a non-final class ('Event') because it uses 'Self' in a non-parameter, non-result type position.
Run Code Online (Sandbox Code Playgroud)

我怎样才能制作这个类final(我不想将 Codegen 设置为手动),或者重写 var chain: [Self]定义?

先感谢您。

extension Event: Chainable {}

protocol Chainable where Self: NSManagedObject {

    var chain: [Self] { get }

    var predecessor: Self? { get set }
    var successor: Self? { get set }

    var selfIndexInChain: Int { get }

    mutating func moveInChain(to index: Int)
    mutating func removeSelfFromChain()

    mutating …
Run Code Online (Sandbox Code Playgroud)

final core-data self swift swift-protocols

5
推荐指数
1
解决办法
391
查看次数

从另一个 Swift 类访问 Obj-C 类中实现的 Swift 协议属性

我见过很多关于在 Swift 中实现 Obj-C 协议的问题,但反之则不然,而且我还没有具体看到这一点。

我正在使用混合 Obj-C / Swift 代码库。我有一个 Swift 协议定义如下:

命名项目.swift

@objc protocol NamedItem {
    var name: String { get }
}
Run Code Online (Sandbox Code Playgroud)

我有一个现有的 Objective-C 类,它目前拥有自己的name属性:

MyObjcClass.h

@interface MyObjcClass : NSObject
@property (nonatomic, strong, readonly) NSString* name;
@end
Run Code Online (Sandbox Code Playgroud)

我还有其他几个具有name属性的类,因此显然我想将它们全部与协议关联起来,而不是类型转换为一堆不同的类型。现在,如果我尝试将 Obj-C 类从拥有自己的属性切换为实现 Swift 协议:

MyObjcClass.h

@protocol MyObjcProtocol
@property (nonatomic, strong, readonly) NSString* place;
@end

@interface MyObjcClass : NSObject
@end
Run Code Online (Sandbox Code Playgroud)

MyObjcClass.m

@interface MyObjcClass () <NamedItem>
@end

@implementation MyObjcClass
@synthesize name = _name;
@synthesize place = _place;
@end …
Run Code Online (Sandbox Code Playgroud)

compiler-errors objective-c swift objective-c-swift-bridge swift-protocols

5
推荐指数
1
解决办法
1259
查看次数

Swift 中是否可以要求关联类型符合关联类型的关联协议?

我正在尝试(基本上没有任何理由)制定一个协议来描述类别理论中的类别。我试图想出这样的东西。

protocol Category {
    associatedtype Object: Protocol
}
protocol Hom {
    associatedtype C: Category
    associatedtype Source: C.Object
    associatedtype Target: C.Object
}
Run Code Online (Sandbox Code Playgroud)

特别是,我希望每个 Hom 类型都有一个关联的类别 C 以及关联的源和目标类型,它们都是该类别中的对象。因此,我将一个对象协议与每个类别相关联,并尝试使 Hom 的源和目标符合相应类别的对象协议。上面的代码无法编译

Type 'Self.Source' constrained to non-protocol, non-class type 'Self.C.Object'
Run Code Online (Sandbox Code Playgroud)

这个错误至少不清楚,因为 C.Object 被声明为协议。有什么办法可以解决这个问题吗?

编辑:

正如 Rob 所指出的,代码本身没有多大意义。Protocol 是 ObjC 中的一个特定类,而不是描述协议的类型。此外,不存在描述所有协议的类型,因为协议本身不能符合协议,因为它们只是对其他类型的要求。我正在寻找的是一个元类型,其中 Any.Protocol、Sequence.Protocol 等都是其实例。

我将更详细地说明我试图描述哪种结构。

类别是一个对象类型以及每对对象实例之间的同态类型。对于 Object 的两个实例 A 和 B,同态类型通常写为 Hom(A,B),但我会写Hom<A,B>为 Swiftier。然后类别配备有带有签名的组合<A: Object, B: Object, C: Object>(_ f: Hom<A,B>, _ g: Hom<B,C>) -> Hom<A,C>

如果 f 是 的实例Hom<A,B>,则 A …

associated-types swift swift-protocols

5
推荐指数
1
解决办法
1971
查看次数

Swift:遵守带有“where”子句的通用方法的协议

概括:

我想创建一个其中Class<T>包含相应ClassDelegate协议的协议func<T>

目标:

通过多个对象类重用单个对象和行为。接收已有专门类的委托回调,无需将对象转换为特定类即可使用它。

示例代码:

具有通用方法的协议:

protocol GenericTableControllerDelegate: AnyObject {
    func controller<T>(controller: GenericTableController<T>, didSelect value: T)
}
Run Code Online (Sandbox Code Playgroud)

通用基子类UITableViewController

open class GenericTableController<DataType>: UITableViewController {
    weak var delegate: GenericTableControllerDelegate?
    var data = [DataType]()

    open override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let item = data[indexPath.row]
        delegate?.controller(controller: self, didSelect: item)
    }
}
Run Code Online (Sandbox Code Playgroud)

的专门版本GenericTableController

final class SpecializedTableController: GenericTableController<NSObject> {}
Run Code Online (Sandbox Code Playgroud)

-的客户端SpecializedTableController实现了结果,但需要类型转换才能访问专用数据类型:

final class ClientOfTableController: UIViewController, GenericTableControllerDelegate {
    // Works OK
    func …
Run Code Online (Sandbox Code Playgroud)

generics protocols ios swift swift-protocols

5
推荐指数
1
解决办法
1314
查看次数

swift 协议扩展默认实现与类中的实际实现

考虑以下代码:

protocol MyProtocol {
    static var name: String { get }
}

extension MyProtocol {
    static var name: String {
        return "unnamed"
    }
}

// does not specify its own name
class MyClass: MyProtocol {

}

//specifies its own name!
class MyClass2: MyProtocol {
    static var name: String {
        return "Specific name"
    }
}

let myClass = MyClass()
print("\(MyClass.name)")
//>>"unnamed"

let myClass2 = MyClass2()
print("\(MyClass2.name)")
//>>"Specific name"
Run Code Online (Sandbox Code Playgroud)

swift 是否保证对于具有协议属性(在本例中为“name”)的实际实现的类(例如在本例中为 MyClass2),这是从类中使用的,而不是默认的“name”实现之一通过协议扩展?

swift swift-protocols

5
推荐指数
1
解决办法
1万
查看次数

获取具有关联类型的协议的“自身”

我有以下协议:

protocol ViewCreator {

  associatedtype ResultView: View

  @ViewBuilder func createView() -> ResultView

}
Run Code Online (Sandbox Code Playgroud)

我想获取它的类型,例如获取它的名称。所以我写了下面的代码:

let typeName = String(describing: ViewCreator.self)
Run Code Online (Sandbox Code Playgroud)

但出现以下错误:

协议“ViewCreator”只能用作通用约束,因为它具有 Self 或关联的类型要求。

在这种情况下,我如何获得具有关联类型的协议的“自身”?

PS我的范围内没有该协议的实现。

swift swift-protocols

5
推荐指数
1
解决办法
472
查看次数

组合类型别名的协议和空一致协议之间的区别

Swift 中这两者有区别吗?

  • protocol ABProtocol: AProtocol, BProtocol {}
  • typealias ABProtocol = AProtocol&BProtocol

swift swift-protocols

5
推荐指数
1
解决办法
116
查看次数

如何使 SwiftUI ViewBuilder 只接受特定协议的视图作为输入块?

我正在尝试使用 SwiftUI@ViewBuilder来允许我的包的用户动态指定视图的正文内容。但是,我试图将可用作输入的可能视图限制为我实现的几个默认视图(出于简化目的)。

这是一个例子:

public protocol PopupBodyView: View { } // every one of my default views conforms to this protocol

func generateChildView(@ViewBuilder items: () -> PopupBodyView)
-> some PopupBodyView {
    return menuItems()
}
Run Code Online (Sandbox Code Playgroud)

如果我现在调用generateChildView,我可以正确指定协议类型的一种PopupBodyView视图- 但是,如果我在结果生成器主体中指定多个视图,则会收到以下错误:

Instance method 'contextMenu(items:)' requires that 'TupleView<(Text, Text)>' conform to 'PopupBodyView'

extension Text: PopupBodyView { } // add protocol conformance

contextMenu {
    Text("Test")
    Text("Test") // Instance method 'contextMenu(items:)' requires that 'TupleView<(Text, Text)>' conform to 'PopupBodyView'
}
Run Code Online (Sandbox Code Playgroud)

我现在如何调整默认值@ViewBuilder以仅接受符合我的自定义 …

generics swift swift-protocols swiftui viewbuilder

5
推荐指数
0
解决办法
350
查看次数

Swift:无法推断通用参数'T'

我有一个名为的协议P,我想写一个函数,它将返回符合该协议的任何类型的实例.

我写了这个:

func f<T: P>() -> T? {
    // ... 
}
Run Code Online (Sandbox Code Playgroud)

但是当我试着打电话时:

var fp = f()
Run Code Online (Sandbox Code Playgroud)

我收到这个错误:Generic parameter 'T' could not be inferred.我做错了什么以及如何解决这个问题?谢谢你的帮助.

swift swift-protocols

4
推荐指数
1
解决办法
1283
查看次数