Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ambiguous use of distinctUntilChanged #70

Closed
vitorhugomagalhaes opened this issue Dec 29, 2016 · 8 comments
Closed

Ambiguous use of distinctUntilChanged #70

vitorhugomagalhaes opened this issue Dec 29, 2016 · 8 comments

Comments

@vitorhugomagalhaes
Copy link

vitorhugomagalhaes commented Dec 29, 2016

Hi,

The following code is causing an ambiguous error:

let observableProducts: RACSignal<AnyObject> = RACObserve(licensingService as! NSObject, "products")
let productChanges = observableProducts.distinctUntilChanged()
Ambiguous use of 'distinctUntilChanged()'
- Found this candidate (ReactiveObjC.RACSignal<ValueType>)
- Found this candidate (ReactiveObjC.RACStream)

The utility class I'm using to bridge RACObserve is:

import Foundation

struct RAC  {
    var target : NSObject!
    var keyPath : String!
    var nilValue : AnyObject!
    
    init(_ target: NSObject!, _ keyPath: String, nilValue: AnyObject? = nil) {
        self.target = target
        self.keyPath = keyPath
        self.nilValue = nilValue
    }
    
    func assignSignal(signal : RACSignal<AnyObject>) {
        signal.setKeyPath(self.keyPath, on: self.target, nilValue: self.nilValue)
    }
}

extension NSObject {
    func RACObserve(_ target: NSObject!,_ keyPath: String) -> RACSignal<AnyObject>! {
        return target.rac_values(forKeyPath: keyPath, observer: self)
    }
}


infix operator <~
func <~ (rac: RAC, signal: RACSignal<AnyObject>!) {
    rac.assignSignal(signal: signal)
}

infix operator ~>
func ~> (signal: RACSignal<AnyObject>!, rac: RAC) {
    rac.assignSignal(signal: signal)
}

Is there any way to workaround this ? I cannot use the pure Swift version for now.

Thanks in advance,

@mdiep
Copy link
Contributor

mdiep commented Dec 29, 2016

@vitorhugomagalhaes
Copy link
Author

vitorhugomagalhaes commented Dec 29, 2016

@mdiep Thanks for the comment.

I'm currently migrating to Swift 3 and that's the main reason for this errors. Still, it must be done.

The problem of using ReactiveObjcBridge + ReactiveSwift is the boilerplate of bridging we will have in the code. A lot of our swift code is exposed to Objective-C and that already sucks.

It could make sense to migrate everything to swift in the near future.

Meanwhile, I found that adding the explicit type seems to work. I still don't understand why it can infer the correct type since the RACObserve function returns a RACSignal type.

Regarding RACStream it does not implement lightweight generics. Is there a reason for it ?

BR,

@andersio
Copy link
Member

/cc @erichoracek

@vitorhugomagalhaes
Copy link
Author

I have divided the several signals to understand where the ambiguity occurs:

            let x1: RACSignal = self.RACObserve(self.settingsService.mib, "user_settings.pois.main_map_visible_categories")
            let x2: RACSignal<AnyObject>! = x1.ignore(nil)
            let x3 = x2.distinctUntilChanged()

Even by explicitly indicating the RACSignal type the compiler still founds it ambiguous.

@erichoracek
Copy link
Contributor

This appears to be due to a Swift compiler issue that results from a method being declared both on a non-generic base class (RACStream), as well as on a generic subclass (RACSignal<ValueType>). Either of the following appear to resolve it:

  1. Declaring RACStream operations (e.g. distinctUntilChanged) as NS_SWIFT_UNAVAILABLE.
  2. Giving RACStream a lightweight generic ValueType annotation.

The second option appears to be the most preferable, since that leaves -[RACStream distinctUntilChanged] available to Swift consumers. Since the NS*/NSMutable* Foundation collections classes appear to work in ObjC and Swift with this pattern, I don't foresee there being an issue with attempting the second approach to fix this issue in RACObjC.

As such, unless anyone knows of any issues, I'll go ahead and make a PR with the second option.

erichoracek added a commit that referenced this issue Dec 31, 2016
Fixes #70

Swift is unable to disambiguate between methods declared both on a non-generic base class and a generic subclass.
erichoracek added a commit to erichoracek/ReactiveObjC that referenced this issue Jan 1, 2017
@erichoracek
Copy link
Contributor

@vitorhugomagalhaes please try 2.1.2 and make sure it resolves your issue. Let me know if it doesn't—thanks!

@vitorhugomagalhaes
Copy link
Author

@erichoracek Thanks.

I will test the new version and get back to you asap.

@erichoracek
Copy link
Contributor

I've filed this issue as https://bugs.swift.org/browse/SR-3529

stuartofmine pushed a commit to stuartofmine/ReactiveObjC_2023 that referenced this issue Oct 18, 2023
Fixes ReactiveCocoa#70

Swift is unable to disambiguate between methods declared both on a non-generic base class and a generic subclass.
stuartofmine pushed a commit to stuartofmine/ReactiveObjC_2023 that referenced this issue Oct 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants