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() | |
} | |
} |
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
// typealias SubclassedDelegateType = protocol<RequiredWorkerMethods, 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, WorkProductType
where ConcreteDelegateType.AuthorityType == T>: NSOperation {
var authority : T
var delegate : ConcreteDelegateType
var operationResult : ConcreteDelegateType.ResultType { return delegate.result }
init(_ someT : T, _ someTD : T.DelegateType) {
authority = someT
delegate = someTD
^^^^ Cannot assign a value of type 'T.DelegateType' to a value of type 'ConcreteDelegateType'
authority.delegate = someTD
super.init()
}
override func start() {
var worker = delegate
worker.begin(authority)
worker.finish = { inResult in self.finished = true }
super.start()
}
}
This compiles for me if I add the T.DelegateType == ConcreteDelegateType constraint:
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 }
}
protocol DelegateOwningType : AnyObject {
typealias DelegateType
// typealias SubclassedDelegateType = protocol<RequiredWorkerMethods, 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,
WorkProductType
where
ConcreteDelegateType.AuthorityType == T,
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
// ^^^^ Cannot assign a value of type 'T.DelegateType' to a value of type 'ConcreteDelegateType'
authority.delegate = someTD
super.init()
}
override func start() {
var worker = delegate
worker.begin(authority)
worker.finish = { inResult in /*FIXME self.finished = true*/ return }
super.start()
}
}
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
I was able to get this to compile, matching the optionality of the
delegate
property on NSNetServiceBrowser, and making its delegate typealias explicit (even though we ought to infer it):