2016-02-22 2 views
0

Я хочу Swizzle метод инициализации инициализации класса NSURLConnection и я попробовал этот код, но это не похоже на работу для меняКак Swizzle метод инициализации класса NSURLConnection

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) 
+0

вы не swizzle селекторов ... вы swizzle метод IMPs. используйте class_replaceMethod. используйте тот же селектор. – nielsbot

+0

Просто заметил это после того, как я отправил ответ: 'class_replaceMethod (NSURLSession.self, swizzledSelector, method_getImplementation (originalMethod), method_getTypeEncoding (originalMethod))' 'NSURLSession'? – yoninja

+0

Я отредактировал мой вопрос @yoninja –

ответ

1
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() 
} 
} 
+0

Я пробовал, как вы сказали, но все равно не повезло мне –

+0

@ManuGupta, я отредактировал свой ответ. – yoninja

+0

Спасибо, решила мою проблему :) –

0

Я думаю, что есть две вещи, которые должны быть зафиксированы:

Как уже упоминался в this answer, вы должны использовать метод Objective-C подпись в originalSelector:

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

Ты ничего не вернулся из my_init метода. Вы должны вернуть тот же тип, что и метод swizzled, в данном случае 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, так как он более современный и имеет более полезные функции.

+0

True! NSURLConnection устарел. Если нет причин для его использования, отбросьте его и используйте NSURLSession. – yoninja

Смежные вопросы