Swift Compiler Crashes on Associatedtype in @Objc Protocol

Swift compiler crashes on associatedtype in @objc protocol

Associated types are Swift-only feature, not visible to Objective-C, so there should be compiler error.

Filed a bug https://bugs.swift.org/browse/SR-3850

Inherit from @objc protocol

From swift-users, seems like a known issue, to be fixed: https://bugs.swift.org/browse/SR-1175

Also now reported as https://bugs.swift.org/browse/SR-3882

Swift Protocol Oriented Networking code crashing Xcode

A crashing compiler is a bug and should be reported. Xcode 9 (beta) does not
crash with your code but gives helpful error messages leading to a solution:


error: generic parameter 'Content' could not be inferred
WebService().load(resource: RepoService) { res in
^

The generic placeholder Content in class WebService<Content> is
not used at all, remove it and make the class non-generic. Then:


error: generic parameter 'R' could not be inferred
WebService().load(resource: RepoService) { res in
^

You have to pass an instance of RepoService to the load method,
and res inside the closure is an optional.

With these changes

final class WebService {
func load<R: Resource>(resource: R, completion: @escaping (R.Content?) -> ()) {
URLSession.shared.dataTask(with: resource.url) { data, _, _ in
let res = data.flatMap(resource.parse)
completion(res)
}.resume()
}
}

WebService().load(resource: RepoService()) { res in
guard let res = res else { return }
for elem in res {
print(elem)
}
}

your code compiles and runs as expected, in Xcode 8.3.3 and 9.

Swift 2.2 #selector in protocol extension compiler error

I had a similar problem. here is what I did.

  1. Marked the protocol as @objc.
  2. Marked any methods I extended with a default behavior as optional.
  3. Then used Self. in the #selector.

    @objc public protocol UpdatableUserInterfaceType {
    optional func startUpdateUITimer()
    optional var updateInterval: NSTimeInterval { get }
    func updateUI(notif: NSTimer)
    }

    public extension UpdatableUserInterfaceType where Self: ViewController {

    var updateUITimer: NSTimer {
    return NSTimer.scheduledTimerWithTimeInterval(updateInterval, target: self, selector: #selector(Self.updateUI(_:)), userInfo: nil, repeats: true)
    }

    func startUpdateUITimer() {
    print(updateUITimer)
    }

    var updateInterval: NSTimeInterval {
    return 60.0
    }
    }

protocol with same associated type name

Another workaround is to create a third, combined protocol:

protocol ReadWrite {
associatedtype R
associatedtype W
func read() -> R
func write(a: W)
}

It's not pretty, since it forces you to redeclare the protocol members, but it does keep it generic (you're not limited to String and Int).



Related Topics



Leave a reply



Submit