如何调配 NSURLConnection 的初始化方法 class
How to swizzle init method of NSURLConnection class
我想调整 NSURLConnection 的 init 初始化方法 class 我已经尝试过这段代码,但它似乎对我不起作用
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)
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()
}
}
我认为有两件事必须解决:
如中所述,您应该在originalSelector
中使用Objective-C方法签名:
`let originalSelector = Selector("initWithRequest:delegate:startImmediately:")`
您没有return my_init
方法中的任何内容。您应该 return 与被调配的方法相同的类型,在本例中为 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)
}
可以看到在swizzled方法中调用了my_init
。在运行时,它将调用原始的 initWithRequest:delegate:startImmediately
,因为此时已经交换了方法。
最后但同样重要的是,NSURLConnection
在 iOS 9 中已弃用。强烈建议改用 NSURLSession
,因为它更现代并且具有更多有用的功能。
我想调整 NSURLConnection 的 init 初始化方法 class 我已经尝试过这段代码,但它似乎对我不起作用
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)
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()
}
}
我认为有两件事必须解决:
如originalSelector
中使用Objective-C方法签名:
`let originalSelector = Selector("initWithRequest:delegate:startImmediately:")`
您没有return my_init
方法中的任何内容。您应该 return 与被调配的方法相同的类型,在本例中为 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)
}
可以看到在swizzled方法中调用了my_init
。在运行时,它将调用原始的 initWithRequest:delegate:startImmediately
,因为此时已经交换了方法。
最后但同样重要的是,NSURLConnection
在 iOS 9 中已弃用。强烈建议改用 NSURLSession
,因为它更现代并且具有更多有用的功能。