我正在尝试构建一组共享通用初始化代码的类。除了继承之外,我认为协议是可行的方法。虽然协议和协议扩展对我来说可以使用实例和静态方法,但我在使其与初始值设定项一起使用时遇到了一些麻烦。
假设我们有这个协议:
protocol CloudServiceWrapper {
static var isConfigured: Bool { get }
init()
func initialize()
}
Run Code Online (Sandbox Code Playgroud)
现在假设我们要在协议扩展中添加isConfigured和的默认实现:init()
extension CloudServiceWrapper {
static var isConfigured: Bool {
get {
return true
}
}
init() {
print("Initializing generic CloudServiceWrapper")
self.init()
if Self.isConfigured {
initialize()
}
}
}
Run Code Online (Sandbox Code Playgroud)
最后,让我们有一个类实现此协议并尝试从其默认实现中受益:
class OneDriveWrapper: CloudServiceWrapper {
required init() {
// CloudServiceWrapper() // error: protocol type 'CloudServiceWrapper' cannot be instantiated
// self = CloudServiceWrapper.init() // error: cannot assign to value: 'self' is immutable
// super.init() …Run Code Online (Sandbox Code Playgroud) 我们已经为我们的s实现了一个协议,Reusable以简化UITableView注册/出队实现UITableViewCell。
protocol Reusable: class {
static var defaultIdentifier: String { get }
}
extension Reusable where Self: UITableViewCell {
static var defaultIdentifier: String {
return String(describing: self)
}
}
class TestTableViewCell: UITableViewCell, Reusable { }
class AnotherTestTableViewCell: UITableViewCell, Reusable { }
Run Code Online (Sandbox Code Playgroud)
然后,有一个扩展UITableView喜欢:
extension UITableView {
func register<T: UITableViewCell & Reusable>(_: T.Type) {
register(UINib(nibName: T.defaultIdentifier, bundle: nil), forCellReuseIdentifier: T.defaultIdentifier)
}
}
Run Code Online (Sandbox Code Playgroud)
以及它的用法:
let tableView: UITableView = UITableView()
tableView.register(TestTableViewCell.self)
tableView.register(AnotherTableViewCell.self)
Run Code Online (Sandbox Code Playgroud)
一切正常,但我们想将这些类型移动到数组中,以便进行排序。这就是我们卡住的地方,这不起作用:
let viewCells = …Run Code Online (Sandbox Code Playgroud) 我正在做一个虚构的练习来尝试实现一个类型擦除的容器。
import Foundation
protocol MoverType {
func move()
}
extension MoverType {
func move() { print("\(type(of: self)) is moving") }
}
class Slithering: MoverType {}
class Walking: MoverType {}
class Trotting: MoverType {}
protocol Animal {
associatedtype Mover: MoverType
var mover: Mover { get }
}
class Snake: Animal {
let mover = Slithering()
}
class Dog: Animal {
let mover = Trotting()
}
class Human: Animal {
let mover = Walking()
}
class AnyAnimal: Animal { // ERROR: Type …Run Code Online (Sandbox Code Playgroud) 鉴于基础类型是相同的,我期望test2是true,而不是false:
protocol Foo {}
class Bar: NSObject, Foo {}
class Test {
func testCompare() {
let b = Bar()
let test1 = compare(expected: Bar.self, actual: b)
let c: Foo = b
let test2 = compare(expected: Bar.self, actual: c)
/*
(lldb) p expected
(@thick NSObject.Type) $R0 = SpokestackTests.Bar
(lldb) p type(of: actual).self
(SpokestackTests.Foo.Type) $R2 = SpokestackTests.Bar
*/
print(test1, test2) // true false
}
func compare<T>(expected: NSObject.Type, actual: T) -> Bool {
return expected == type(of: …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个协议,包含使用UIImagePickerController的过程,使其在我的应用程序中更流线型.我基本上有这样的事情:
public protocol MediaAccessor : UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func mediaCaptured(title: String, fileData: NSData, fileType: String)
}
Run Code Online (Sandbox Code Playgroud)
和一个扩展,它完成了请求权限和处理委托方法的所有繁重工作:
public extension MediaAccessor where Self : UIViewController {
public func captureMedia() {
//All sorts of checks for picker authorization
let picker = UIImagePickerController()
picker.delegate = self
self.presentViewController(picker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
//implementation of the delegate in extension
//even though everything compiles, this method is not called on picker completion
}
} …Run Code Online (Sandbox Code Playgroud) 我有一个复杂的视图类,
class Snap:UIViewController, UIScrollViewDelegate
{
}
Run Code Online (Sandbox Code Playgroud)
最终的结果是,用户可以选择一种颜色......
protocol SnapProtocol:class
{
func colorPicked(i:Int)
}
class Snap:UIViewController, UIScrollViewDelegate
{
someDelegate.colorPicked(blah)
}
Run Code Online (Sandbox Code Playgroud)
那么谁将会处理它.
让我们说你肯定知道响应者链上有什么东西,甚至走过容器视图,这是一个SnapProtocol.如果是这样,您可以使用这个可爱的代码来调用它
var r : UIResponder = self
repeat { r = r.nextResponder()! } while !(r is SnapProtocol)
(r as! SnapProtocol).colorPicked(x)
Run Code Online (Sandbox Code Playgroud)
如果您愿意,可以使用此最佳扩展名
public extension UIResponder // walk up responder chain
{
public func next<T>() -> T?
{
guard let responder = self.nextResponder()
else { return nil }
return (responder as? T) ?? responder.next()
}
} …Run Code Online (Sandbox Code Playgroud) 我有一些代码用于_ArrayType在Swift 3之前继续.我试图了解公共协议发生了什么_ArrayType.
任何的想法?
protocol BasePresenterProtocol : class {}
protocol DashboardPresenterProtocol : BasePresenterProtocol {}
final class DashboardPresenter {
weak var view: DashboardPresenterProtocol?
init() {
self.view = DashboardViewController()
}
func test() {
print("Hello")
}
}
extension DashboardPresenter: DashboardViewProtocol { }
protocol BaseViewProtocol : class {
weak var view: BasePresenterProtocol? { get set }
}
protocol DashboardViewProtocol : BaseViewProtocol {
}
class DashboardViewController {
}
extension DashboardViewController: DashboardPresenterProtocol { }
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我在下一行收到错误
extension DashboardPresenter: DashboardViewProtocol { }
Run Code Online (Sandbox Code Playgroud)
那个,DashboardPresenter不向协议确认DashboardViewProtocol,但我已经宣布weak var view: DashboardPresenterProtocol?了 …
我正在编写一个具有readOnly标签的协议.我想扩展它并给它一个默认的实现,其中符合类型是a UITextView.
码:
protocol CountingView {
var keyboardLabel : UILabel {get}
}
extension CountingView where Self : UITextView {
var keyboardLabel : UILabel {
get {
let label = UILabel()
label.textColor = UIColor.white
label.translatesAutoresizingMaskIntoConstraints = false
return label
}
private (set) {
keyboardLabel = newValue
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我添加private之前,set我得到以下错误.
期望'get','set','willSet'或'didSet'关键字来启动访问者定义
我查看了这个错误的其他问题,但没有发现它们与我的相关.
当尝试符合NSItemProviderReading时,我收到以下错误:

该方法的协议定义如下:
public static func object(withItemProviderData data: Data, typeIdentifier: String) throws -> Self
Run Code Online (Sandbox Code Playgroud)
协议静态函数返回类型"Self",我试图将其更改为实际类的名称,但之后它将不再符合NSItemProviderReading.
如何归还"自我"?
它附加为!自我,但后来显示2个错误和这个警告,它看起来很混乱,因为它似乎想要恢复到以前的状态,在这种情况下返回类的实例NameData
swift ×10
swift-protocols ×10
ios ×4
generics ×2
messaging ×1
private ×1
protocols ×1
singleton ×1
swift3 ×1
type-erasure ×1