Created
September 19, 2015 02:03
-
-
Save thekarladam/c3974dc545d56b41ee5b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
protocol DelegateOwningType { | |
typealias DelegateType | |
var delegate : DelegateType { get set } | |
} | |
class DelegatedOperation <T : DelegateOwningType, TDelegate where T.DelegateType == TDelegate.Type>: NSOperation { | |
let authority : T | |
var delegate : TDelegate | |
init(someT : T, someTD : TDelegate) { | |
authority = someT | |
delegate = someTD | |
authority.delegate = someTD | |
super.init() | |
} | |
} |
I think our compilers may not be in sync because I get this error every time
enum Result<T, Error: ErrorType> {
case Success(T)
case Failure(Error)
}
protocol RequiredWorkerMethods {
typealias ResultType
func begin(authority : AnyObject)
var finish : (ResultType) -> Void { get set }
var result : ResultType { get set }
}
protocol DelegateOwningType : AnyObject {
typealias DelegateType
var delegate : DelegateType? { get set }
}
extension NSNetServiceBrowser : DelegateOwningType {
typealias DelegateType = NSNetServiceBrowserDelegate
}
extension NSNetServicesError : ErrorType {}
protocol ConcreteWorker : RequiredWorkerMethods {
typealias AuthorityType
}
class DelegatedOperation <T : DelegateOwningType, ConcreteDelegateType : ConcreteWorker
where T.DelegateType == ConcreteDelegateType>: NSOperation {
var authority : T
var delegate : ConcreteDelegateType
var operationResult : ConcreteDelegateType.ResultType { return delegate.result }
init(_ someT : T, _ someTD : T.DelegateType) {
authority = someT
delegate = someTD
authority.delegate = someTD
super.init()
}
override func start() {
var worker = delegate
worker.begin(authority)
worker.finish = { inResult in }
super.start()
}
}
class ConcreteFoo : NSObject, NSNetServiceBrowserDelegate, NSNetServiceDelegate, ConcreteWorker {
typealias ResultType = Result<[AnyObject], NSNetServicesError>
typealias AuthorityType = NSNetServiceBrowser
var encounteredError : NSNetServicesError?
var finish : (ResultType) -> Void
var result : ResultType
override init() {}
func begin(authority: AnyObject) {}
}
let serviceLookup = DelegatedOperation<NSNetServiceBrowser, ConcreteFoo>(NSNetServiceBrowser(), ConcreteFoo())
^^^^'DelegatedOperation' requires the types 'DelegateType' (aka 'NSNetServiceBrowserDelegate') and 'ConcreteFoo' be equivalent
Because I have to specify the type, the compiler won't accept it as a protocol and I can't declare conformance to as the compiler doesn't regard type aliases as complete types and there's no way to hint it as merely being a protocol
I see, yeah, you wouldn't be able to use ConcreteFoo as the ConcreteDelegateType and satisfy the same-type constraint. You need some way to say "I want an NSNetServiceBrowser with a specific delegate type". You could use a wrapper struct for that:
protocol DelegateOwningType {
typealias DelegateType
var delegate : DelegateType? { get nonmutating set }
}
struct ConcreteNSNetServiceBrowser<T: NSNetServiceBrowserDelegate>: DelegateOwningType {
var browser: NSNetServiceBrowser
var delegate: T? {
get {
return browser.delegate as! T?
}
set {
browser.delegate = newValue
}
}
}
which I think will work better. That lets this work:
import Foundation
enum Result<T, Error: ErrorType> {
case Success(T)
case Failure(Error)
}
protocol RequiredWorkerMethods {
typealias ResultType
func begin(authority : AnyObject)
var finish : (ResultType) -> Void { get set }
var result : ResultType? { get set }
}
struct ConcreteNSNetServiceBrowser<T: NSNetServiceBrowserDelegate> {
var browser: NSNetServiceBrowser
var delegate: T? {
get {
return browser.delegate as! T?
}
set {
browser.delegate = newValue
}
}
}
extension NSNetServicesError : ErrorType {}
protocol ConcreteWorker : RequiredWorkerMethods {
typealias AuthorityType
}
class DelegatedOperation <
ConcreteDelegateType: protocol<NSNetServiceBrowserDelegate, ConcreteWorker>
>: NSOperation {
var authority : ConcreteNSNetServiceBrowser<ConcreteDelegateType>
var delegate : ConcreteDelegateType
var operationResult : ConcreteDelegateType.ResultType { return delegate.result! }
init(_ someT : ConcreteNSNetServiceBrowser<ConcreteDelegateType>, _ someTD : ConcreteDelegateType) {
authority = someT
delegate = someTD
authority.delegate = someTD
super.init()
}
override func start() {
var worker = delegate
worker.begin(authority.browser)
worker.finish = { inResult in }
super.start()
}
}
class ConcreteFoo : NSObject, NSNetServiceBrowserDelegate, NSNetServiceDelegate, ConcreteWorker {
typealias ResultType = Result<[AnyObject], NSNetServicesError>
typealias AuthorityType = NSNetServiceBrowser
var encounteredError : NSNetServicesError?
var finish : (ResultType) -> Void
var result : ResultType?
override init() {
self.finish = {_ in}
}
func begin(authority: AnyObject) {}
}
let serviceLookup = DelegatedOperation<ConcreteFoo>(
ConcreteNSNetServiceBrowser(browser: NSNetServiceBrowser()),
ConcreteFoo()
)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This compiles for me if I add the T.DelegateType == ConcreteDelegateType constraint: