0

我想调整 NSURLConnection 类的 init init 方法,我已经尝试过这段代码,但它似乎对我不起作用

extension NSURLConnection{
public override class func initialize() {
    struct Static {
        static var token: dispatch_once_t = 0
    }
    dispatch_once(&Static.token) {
        let originalSelector = Selector("init:delegate:startImmediately:")
        let swizzledSelector = Selector("my_init:delegate:startImmediately:")

        let originalMethod = class_getInstanceMethod(self, originalSelector)
        let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)

        let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))

        if didAddMethod {
            class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod)
        }
    }
}

// MARK: - Method Swizzling
func my_init(request: NSURLRequest, delegate: AnyObject?, startImmediately: Bool){
 print("Inside Swizzled Method")
}
}

这是我从视图控制器发起的请求

let testPoint: String = "www.google.com"
    guard let url = NSURL(string: testPoint) else {
        print("Error: cannot create URL")
        return
    }
    let urlRequest = NSURLRequest(URL: url)
    let conn = NSURLConnection(request: urlRequest, delegate: self, startImmediately: true)
4

2 回答 2

2
extension NSURLConnection{
public override class func initialize() {
    struct Static {
        static var token: dispatch_once_t = 0
    }

    if self !== NSURLConnection.self {
        return
    }

    dispatch_once(&Static.token) {
        let originalSelector = Selector("initWithRequest:delegate:startImmediately:")
        let swizzledSelector = Selector("initWithTest:delegate:startImmediately:")

        let originalMethod = class_getInstanceMethod(self, originalSelector)
        let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)

        let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))

        if didAddMethod {
            class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod)
        }
    }
}

// MARK: - Method Swizzling
convenience init(test: NSURLRequest, delegate: AnyObject?, startImmediately: Bool){
    print("Inside Swizzled Method")
    self.init()
}
}
于 2016-02-22T08:21:39.647 回答
0

我认为有两点需要解决:

this answer中所述,您应该在以下位置使用Objective-C方法签名originalSelector

`let originalSelector = Selector("initWithRequest:delegate:startImmediately:")`

您不会从my_init方法中返回任何内容。在这种情况下,您应该返回与被调配的方法相同的类型NSURLConnection

func my_init(request: NSURLRequest, delegate: AnyObject?, startImmediately: Bool) -> NSURLConnection? {
    print("Inside Swizzled Method")
    //call the original initializer
    return my_init( request, delegate: delegate, startImmediately: startImmediately)
}

您可以看到它my_init在 swizzled 方法中被调用。在运行时,它将调用原始initWithRequest:delegate:startImmediately方法,因为此时方法已被交换。

最后但同样重要的NSURLConnection是,在 iOS 9 中已弃用。强烈建议改用NSURLSession它,因为它更现代且具有更多有用的功能。

于 2016-02-22T08:58:28.840 回答