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")
}
}

そして、ここに私がView Controllerから開始しているリクエストがあります

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

修正する必要があるのは次の 2 点だと思います。

この回答で述べたように、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_initswizzled メソッドで呼び出されていることがわかります。initWithRequest:delegate:startImmediatelyメソッドはこの時点ですでに交換されているため、ランタイムでは、元のメソッドが呼び出されます。

最後になりましたがNSURLConnection、iOS 9 では非推奨NSURLSessionです。より最新で、より便利な機能を備えているため、代わりに使用することを強くお勧めします。

于 2016-02-22T08:58:28.840 に答える