Swift override function in extension

If I have a class:

class Spaceship<FuelType> {
    function prepareForLiftoff() throws {
        //Start the countdown!
    }
}

It was originally supposed that I could override prepareForLiftoffwithout subclassing by adding the extension:

extension Spaceship where FuelType: CollectionType {
    func prepareForLiftoff() throws {}
} 

This code does not compile, but the error says about the invalid redeclarationfunction, which makes sense.

My question is: Is there a way to override a function of a particular class? In other words, I can replace functionality under certain conditions, such as the example above, where FuelType: CollectionType. If not, is there another way or way to achieve this behavior (perhaps declaring a different protocol, idk)

Now that I think about it more, I have to say that this is impossible, because in order to stop someone from overriding any standard library functions?

+2
2

documentation:

, .

, .

:

, .

+14

, , swizzling. , viewWillAppear. Swift 3:

extension UIViewController {
    open override class func initialize() {
        // make sure this isn't a subclass
        guard self === UIViewController.self else { return }
        DispatchQueue.once(token: "viewWillAppear") {
            let originalSelector = #selector(self.viewWillAppear(_:))
            let swizzledSelector = #selector(self.proj_viewWillAppear1(animated:))
            let originalMethod = class_getInstanceMethod(self, originalSelector)
            let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)
            method_exchangeImplementations(originalMethod, swizzledMethod)
        }
    }

    func proj_viewWillAppear1(animated: Bool) {
        self.proj_viewWillAppear1(animated: animated)
        let viewControllerName = NSStringFromClass(type(of: self))
        print("viewWillAppear: \(viewControllerName)")
    }
}

20170621

public extension DispatchQueue {
    private static var _onceTracker = [String]()

    public class func once(file: String = #file, function: String = #function, line: Int = #line, block:(Void)->Void) {
        let token = file + ":" + function + ":" + String(line)
        once(token: token, block: block)
    }

    public class func once(token: String, block:(Void)->Void) {
        objc_sync_enter(self)
        defer { objc_sync_exit(self) }

        if _onceTracker.contains(token) {
            return
        }

        _onceTracker.append(token)
        block()
    }
}
+1

Source: https://habr.com/ru/post/1685331/


All Articles