Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Partial function application with generics

I'm working with an Observer API (ObserverSet) which have the following function :

public func add<T: AnyObject>(object: T, _ f: T -> Parameters -> Void) -> ObserverSetEntry<Parameters>

It simply register an object then call the instance method f on the object when notification triggers

In one of my manager, I need to hide the previous function with one of mine so I can force an observer to call a predefine function implemented via a protocol.

Here's what I've done so far :

@objc protocol Observer : NSObjectProtocol {
    func observe(param: String) -> Void
}

func addObserver<T: AnyObject where T: Observer>(observer: T) {
    let f: T -> String -> Void = observer.dynamicType.observe
    entries.addObserver(observer, f)
}

Unfortunately, I have the following error showing up Partial application of generic method is not allowed

I've found a possible workaround somewhere on SO which look like that :

let f: T -> String -> Void = { (obs: T) in obs.dynamicType.observe(obs) }

But this line of code drives my XCode crazy with some Segmentation Fault: 11 on compilation (and Communication interrupted with Playground ..)

Is there any workaround for what I'm trying to do ?

like image 989
Yaman Avatar asked Feb 05 '15 20:02

Yaman


Video Answer


1 Answers

I haven't tested but you can try:

@objc protocol Observer : NSObjectProtocol {
    func observe(param: String) -> Void
}

func addObserver<T: AnyObject where T: Observer>(observer: T) {
    let f: T -> String -> Void = { ($0 as AnyObject).observe }
    entries.addObserver(observer, f)
}

At least, this compiles because AnyObject has all methods from ObjC - including @objc - classes/protocols, as ImplicitlyUnwrappedOptional.

So, this compiles:

let str = NSString(string: "test")
(str as AnyObject).observe("foo")

Of course this causes runtime error because NSString has no observe(_:) method. But, in your case, T is guaranteed to be Observer, it should works.

like image 124
rintaro Avatar answered Sep 28 '22 17:09

rintaro