Coder Social home page Coder Social logo

Comments (6)

kean avatar kean commented on May 17, 2024

Ok, I've just tested it and I can confirm that Swift calls the default implementation provided in public extension ImageDisplayingView where Self: View, which shouldn't be the case.

from nuke.

kean avatar kean commented on May 17, 2024

As a workaround you can set a custom handler on ImageViewLoadingController:

class CustomImageView: UIImageView {
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.nk_imageLoadingController.handler = { task, response, options in
            // your nk_imageTask(task: ImageTask, didFinishWithResponse response: ImageResponse, options: ImageViewLoadingOptions?) implementation
        }
    }
}

from nuke.

ValCanBuild avatar ValCanBuild commented on May 17, 2024

Thank, Kean, that works great. Want me to close the issue or will you leave it open to investigate?

from nuke.

kean avatar kean commented on May 17, 2024

Please leave it open. Users should be able to override methods declared in ImageDisplayingView protocol, at least that was the intended behaviour. I should figure out why virtual dispatch doesn't work here.

from nuke.

kean avatar kean commented on May 17, 2024

After some research I've found several different issues related to methods dispatch with protocol extensions that still hasn't been fixed in Xcode 7.

Here's the related one http://www.openradar.me/23067007. You have class A that conforms to protocol P that has default implementation of method foo. If you create subclass B of class A and implement method foo it never gets called unless class A also provides an implementation of foo method.

And that's how it works in Nuke:

  1. If you implement nk_imageTask(_:didFinishWithResponse:options:) method in a class that declares conformance to ImageDisplayingView protocol (for instance UIImageView) then this method gets called (as expected):
    extension UIImageView: ImageDisplayingView, ImageLoadingView {
        public var nk_image: UIImage? {
            get { return self.image }
            set { self.image = newValue }
        }

        public func nk_imageTask(task: ImageTask, didFinishWithResponse response: ImageResponse, options: ImageViewLoadingOptions?) {
            print("UIImageView method called")
        }
    }
  1. However if you implement nk_imageTask(_:didFinishWithResponse:options:) method in a subclass of UIImageView and don't implement this method in UIImageView then this method never gets called (this is a bug which is the same as in the radar).
public class NKImageView: UIImageView {

}

extension NKImageView {
    public override var nk_image: UIImage? {
        get { return self.image }
        set { self.image = newValue }
    }

    public func nk_imageTask(task: ImageTask, didFinishWithResponse response: ImageResponse, options: ImageViewLoadingOptions?) {
        print("NKImageView method never gets called")
    }
}
  1. If you implement nk_imageTask(_:didFinishWithResponse:options:) method in both UIImageView and NKImageView classes then you get the following error in NKImageView class (as of Xcode 7.1):

screen shot 2015-11-13 at 02 29 55

The error message is pretty obvious. And as you can see properties already can be overridden and get called as expected.

from nuke.

kean avatar kean commented on May 17, 2024

This behaviour (http://www.openradar.me/23067007) doesn't match the documentation that clearly states that:

You can use protocol extensions to provide a default implementation to any method or property requirement of that protocol. If a conforming type provides its own implementation of a required method or property, that implementation will be used instead of the one provided by the extension.

Same thing holds with extensions with where clauses (which I've also tested):

If a conforming type satisfies the requirements for multiple constrained extensions that provide implementations for the same method or property, Swift will use the implementation corresponding to the most specialized constraints.

from nuke.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.