Swift override function in extension

后端 未结 2 919
慢半拍i
慢半拍i 2020-12-02 02:17

If I have a class:

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

I ori

相关标签:
2条回答
  • 2020-12-02 02:31

    From the documentation:

    Extensions can add new functionality to a type, but they cannot override existing functionality.

    The documentation lists carefully and precisely what an extension is allowed to do.

    As to your question:

    Is there anyway to override a function of a particular class

    Yes, it's called subclassing.

    0 讨论(0)
  • 2020-12-02 02:35

    Instead of overriding, you may like to try swizzling. For example the following code allows you to run your own 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)")
        }
    }
    

    Update 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()
        }
    }
    
    0 讨论(0)
提交回复
热议问题