diff --git a/Documents/README.zh-Hans.md b/Documents/README.zh-Hans.md index 5445e019..ceaa0a2a 100644 --- a/Documents/README.zh-Hans.md +++ b/Documents/README.zh-Hans.md @@ -24,7 +24,7 @@ let token = try hookBefore(object: obj, selector: #selector(TestObject.testMetho } obj.testMethod() -token.cancelHook() // cancel the hook +token.revert() // cancel the hook ``` 2. hook某个实例的某个方法,在目标方法执行之后调用 hook 闭包,并且获取方法的参数。 @@ -49,7 +49,7 @@ let token = try hookAfter(object: obj, selector: #selector(TestObject.testMethod ) obj.testMethod("ABC") -token.cancelHook() // cancel the hook +token.revert() // cancel the hook ``` 3. hook某个实例的某个方法,用 hook 闭包完全取代目标方法。 @@ -100,7 +100,7 @@ let token = try hookBefore(targetClass: TestObject.self, selector: #selector(Tes let obj = TestObject() obj.testMethod() -token.cancelHook() // cancel the hook +token.revert() // cancel the hook ``` 5. hook某个类的某个类方法或静态方法,在目标方法执行之前调用 hook 闭包。 diff --git a/Package.resolved b/Package.resolved index 4881bca3..1868b2c1 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,16 +1,14 @@ { - "object": { - "pins": [ - { - "package": "libffi_iOS", - "repositoryURL": "https://github.com/623637646/libffi.git", - "state": { - "branch": null, - "revision": "c006945112296b8dc4c47bf70cd3ad5fc31488cf", - "version": "3.3.6-iOS" - } + "pins" : [ + { + "identity" : "libffi", + "kind" : "remoteSourceControl", + "location" : "https://github.com/623637646/libffi.git", + "state" : { + "revision" : "ba435e5a3b38cf2eede5974d3e2bd3c737f066e1", + "version" : "3.4.7" } - ] - }, - "version": 1 + } + ], + "version" : 2 } diff --git a/PerformanceTests/PerformanceTests.m b/PerformanceTests/PerformanceTests.m index c33a8e60..90658242 100644 --- a/PerformanceTests/PerformanceTests.m +++ b/PerformanceTests/PerformanceTests.m @@ -40,12 +40,12 @@ - (void)testHookBeforeForAllInstance { NSTimeInterval aspectsTime = [self executionTimeWithObject:testObject]; XCTAssertTrue([aspectsToken remove]); - OCToken *swiftHookToken = [TestObject sh_hookBeforeSelector:@selector(emptyMethod) error:&error closure:^{ + HookToken *swiftHookToken = [TestObject sh_hookBeforeSelector:@selector(emptyMethod) error:&error closure:^{ }]; XCTAssertNil(error); NSTimeInterval swiftHookTime = [self executionTimeWithObject:testObject]; - [swiftHookToken cancelHook]; + [swiftHookToken revert]; [self log:@"Hook with Befre mode for all instances" nonHookTime: nonHookTime aspectsTime: aspectsTime swiftHookTime: swiftHookTime]; XCTAssert(aspectsTime / swiftHookTime > 10 && aspectsTime / swiftHookTime < 30); @@ -64,13 +64,13 @@ - (void)testHookInsteadForAllInstance { NSTimeInterval aspectsTime = [self executionTimeWithObject:testObject]; XCTAssertTrue([aspectsToken remove]); - OCToken *swiftHookToken = [TestObject sh_hookInsteadWithSelector:@selector(emptyMethod) closure:^(void(^original)(NSObject *, SEL), NSObject *object, SEL selector){ + HookToken *swiftHookToken = [TestObject sh_hookInsteadWithSelector:@selector(emptyMethod) closure:^(void(^original)(NSObject *, SEL), NSObject *object, SEL selector){ original(object, selector); } error:&error]; XCTAssertNil(error); NSTimeInterval swiftHookTime = [self executionTimeWithObject:testObject]; - [swiftHookToken cancelHook]; + [swiftHookToken revert]; [self log:@"Hook with Instead mode for all instances" nonHookTime: nonHookTime aspectsTime: aspectsTime swiftHookTime: swiftHookTime]; XCTAssert(aspectsTime / swiftHookTime > 3 && aspectsTime / swiftHookTime < 9); @@ -88,12 +88,12 @@ - (void)testHookAfterForSingleInstance { NSTimeInterval aspectsTime = [self executionTimeWithObject:testObject]; XCTAssertTrue([aspectsToken remove]); - OCToken *swiftHookToken = [testObject sh_hookAfterSelector:@selector(emptyMethod) error:&error closure:^{ + HookToken *swiftHookToken = [testObject sh_hookAfterSelector:@selector(emptyMethod) error:&error closure:^{ }]; XCTAssertNil(error); NSTimeInterval swiftHookTime = [self executionTimeWithObject:testObject]; - [swiftHookToken cancelHook]; + [swiftHookToken revert]; [self log:@"Hook with After mode for single instances" nonHookTime: nonHookTime aspectsTime: aspectsTime swiftHookTime: swiftHookTime]; XCTAssert(aspectsTime / swiftHookTime > 3 && aspectsTime / swiftHookTime < 9); @@ -112,13 +112,13 @@ - (void)testHookInsteadForSingleInstance { NSTimeInterval aspectsTime = [self executionTimeWithObject:testObject]; XCTAssertTrue([aspectsToken remove]); - OCToken *swiftHookToken = [testObject sh_hookInsteadWithSelector:@selector(emptyMethod) closure:^(void(^original)(NSObject *, SEL), NSObject *object, SEL selector){ + HookToken *swiftHookToken = [testObject sh_hookInsteadWithSelector:@selector(emptyMethod) closure:^(void(^original)(NSObject *, SEL), NSObject *object, SEL selector){ original(object, selector); } error:&error]; XCTAssertNil(error); NSTimeInterval swiftHookTime = [self executionTimeWithObject:testObject]; - [swiftHookToken cancelHook]; + [swiftHookToken revert]; [self log:@"Hook with Instead mode for single instances" nonHookTime: nonHookTime aspectsTime: aspectsTime swiftHookTime: swiftHookTime]; XCTAssert(aspectsTime / swiftHookTime > 1.5 && aspectsTime / swiftHookTime < 3.5); diff --git a/README.md b/README.md index 5db1f375..8a495484 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ let token = try hookBefore(object: obj, selector: #selector(TestObject.testMetho } obj.testMethod() -token.cancelHook() // cancel the hook +token.revert() // cancel the hook ``` 2. Call the hook closure **after** executing **specified instance**'s method and get the parameters. @@ -50,7 +50,7 @@ let token = try hookAfter(object: obj, selector: #selector(TestObject.testMethod ) obj.testMethod("ABC") -token.cancelHook() // cancel the hook +token.revert() // cancel the hook ``` 3. Totally override the mehtod for **specified instance**. @@ -100,7 +100,7 @@ let token = try hookBefore(targetClass: TestObject.self, selector: #selector(Tes let obj = TestObject() obj.testMethod() -token.cancelHook() // cancel the hook +token.revert() // cancel the hook ``` 5. Call the hook closure **before** executing the **class method**. diff --git a/SwiftHook/Classes/Hook/HookDeallocAfterDelegate.swift b/SwiftHook/Classes/Hook/HookDeallocAfterDelegate.swift index bc12fe1c..e546588c 100644 --- a/SwiftHook/Classes/Hook/HookDeallocAfterDelegate.swift +++ b/SwiftHook/Classes/Hook/HookDeallocAfterDelegate.swift @@ -8,42 +8,8 @@ import Foundation -private var associatedDelegateHandle: UInt8 = 0 - -private class HookDeallocAfterDelegate { - - var hookClosures = [AnyObject]() - - deinit { - for item in hookClosures.reversed() { - unsafeBitCast(item, to: (@convention(block) () -> Void).self)() - } - } -} - -private struct HookDeallocAfterToken: Token { - - weak var delegate: HookDeallocAfterDelegate? - weak var closure: AnyObject? - - init(delegate: HookDeallocAfterDelegate, closure: AnyObject) { - self.delegate = delegate - self.closure = closure - } - - func cancelHook() { - delegate?.hookClosures.removeAll(where: {(closure) -> Bool in - return closure === self.closure - }) - } -} - -func hookDeallocAfterByDelegate(object: AnyObject, closure: AnyObject) -> Token { - var delegate: HookDeallocAfterDelegate! = objc_getAssociatedObject(object, &associatedDelegateHandle) as? HookDeallocAfterDelegate - if delegate == nil { - delegate = HookDeallocAfterDelegate() - objc_setAssociatedObject(object, &associatedDelegateHandle, delegate, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - } - delegate.hookClosures.append(closure) - return HookDeallocAfterToken.init(delegate: delegate, closure: closure) +func hookDeallocAfterByDelegate(object: AnyObject, closure: AnyObject) -> HookToken { + let token = HookToken(deallocAfter: object, hookClosure: closure) + _ = token.apply() + return token } diff --git a/SwiftHook/Classes/Hook/HookInternal.swift b/SwiftHook/Classes/Hook/HookInternal.swift index 75aa0bf1..cddddefd 100644 --- a/SwiftHook/Classes/Hook/HookInternal.swift +++ b/SwiftHook/Classes/Hook/HookInternal.swift @@ -8,44 +8,51 @@ import Foundation -enum HookMode { +@objc public enum HookMode: Int { case before case after case instead } func internalHook(targetClass: AnyClass, selector: Selector, mode: HookMode, hookClosure: AnyObject) throws -> HookToken { - let hookContext = try getHookContext(targetClass: targetClass, selector: selector, isSpecifiedInstance: false) - try hookContext.append(hookClosure: hookClosure, mode: mode) - return HookToken(hookContext: hookContext, hookClosure: hookClosure, mode: mode) + let token = try HookToken(targetClass: targetClass, selector: selector, mode: mode, hookClosure: hookClosure) + try internalApplyHook(token: token) + return token } func internalHook(object: AnyObject, selector: Selector, mode: HookMode, hookClosure: AnyObject) throws -> HookToken { - let targetClass: AnyClass - if let object = object as? NSObject { - guard try isSupportedKVO(object: object) else { - throw SwiftHookError.hookKVOUnsupportedInstance - } - // use KVO for specified instance hook - try wrapKVOIfNeeded(object: object, selector: selector) - guard let KVOedClass = object_getClass(object) else { - throw SwiftHookError.internalError(file: #file, line: #line) - } - targetClass = KVOedClass - } else { - // create dynamic class for specified instance hook - guard let baseClass = object_getClass(object) else { - throw SwiftHookError.internalError(file: #file, line: #line) + let token = try HookToken(object: object, selector: selector, mode: mode, hookClosure: hookClosure) + try internalApplyHook(token: token) + return token +} + +func internalApplyHook(token: HookToken) throws { + if let targetClass = token.targetClass { + let hookContext = try getHookContext(targetClass: targetClass, selector: token.selector, isSpecifiedInstance: false) + try hookContext.append(hookClosure: token.hookClosure, mode: token.mode) + token.hookContext = hookContext + } else if let object = token.hookObject { + let targetClass: AnyClass + if let object = object as? NSObject { + guard try isSupportedKVO(object: object) else { + throw SwiftHookError.hookKVOUnsupportedInstance + } + // use KVO for specified instance hook + try wrapKVOIfNeeded(object: object, selector: token.selector) + guard let KVOedClass = object_getClass(object) else { + throw SwiftHookError.internalError(file: #file, line: #line) + } + targetClass = KVOedClass + } else { + // create dynamic class for specified instance hook + targetClass = try wrapDynamicClass(object: object) } - targetClass = isDynamicClass(targetClass: baseClass) ? baseClass : try wrapDynamicClass(object: object) + // hook + let hookContext = try getHookContext(targetClass: targetClass, selector: token.selector, isSpecifiedInstance: true) + // set hook closure + try appendHookClosure(object: object, selector: token.selector, hookClosure: token.hookClosure, mode: token.mode) + token.hookContext = hookContext } - // hook - let hookContext = try getHookContext(targetClass: targetClass, selector: selector, isSpecifiedInstance: true) - var token = HookToken(hookContext: hookContext, hookClosure: hookClosure, mode: mode) - token.hookObject = object - // set hook closure - try appendHookClosure(object: object, selector: selector, hookClosure: hookClosure, mode: mode) - return token } /** @@ -58,7 +65,7 @@ func internalHook(object: AnyObject, selector: Selector, mode: HookMode, hookClo # Case 2: Hook all instance or hook class method. Try to change the Method's IMP from hooked to original and released context. - But it's dangerous when the current IMP is not previous hooked IMP. In this case. cancelHook() still works fine but the context will not be released. + But it's dangerous when the current IMP is not previous hooked IMP. In this case. revert() still works fine but the context will not be released. 1. Return true if the context will be released. 2. Return false if the context will not be released. 3. Returen nil means some issues like token already canceled. @@ -79,11 +86,8 @@ func internalCancelHook(token: HookToken) throws -> Bool? { // The object has been deinit. return nil } - guard let hookClosure = token.hookClosure else { - // Token has been canceled. - return nil - } - try removeHookClosure(object: hookObject, selector: hookContext.selector, hookClosure: hookClosure, mode: token.mode) + try removeHookClosure(object: hookObject, selector: hookContext.selector, hookClosure: token.hookClosure, mode: token.mode) + token.hookContext = nil guard object_getClass(hookObject) == hookContext.targetClass else { // The class is changed after hooking by SwiftHook. @@ -106,10 +110,8 @@ func internalCancelHook(token: HookToken) throws -> Bool? { return true } else { // This hook is for all instance or class method - guard let hookClosure = token.hookClosure else { - throw SwiftHookError.internalError(file: #file, line: #line) - } - try hookContext.remove(hookClosure: hookClosure, mode: token.mode) + try hookContext.remove(hookClosure: token.hookClosure, mode: token.mode) + token.hookContext = nil guard !(try isIMPChanged(hookContext: hookContext)) else { // The IMP is changed after hooking by SwiftHook. return false diff --git a/SwiftHook/Classes/Public/HookAllInstances.swift b/SwiftHook/Classes/Public/HookAllInstances.swift index 2a1401d4..c040d247 100644 --- a/SwiftHook/Classes/Public/HookAllInstances.swift +++ b/SwiftHook/Classes/Public/HookAllInstances.swift @@ -25,7 +25,7 @@ import Foundation print("hooked") }) _ = MyObject().sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter targetClass: The class you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -33,7 +33,7 @@ import Foundation - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookBefore(targetClass: AnyClass, selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> Token { +public func hookBefore(targetClass: AnyClass, selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> HookToken { return try hookBefore(targetClass: targetClass, selector: selector, closure: closure as Any) } @@ -52,7 +52,7 @@ public func hookBefore(targetClass: AnyClass, selector: Selector, closure: @esca print("hooked") }) _ = MyObject().sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter targetClass: The class you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -60,7 +60,7 @@ public func hookBefore(targetClass: AnyClass, selector: Selector, closure: @esca - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookAfter(targetClass: AnyClass, selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> Token { +public func hookAfter(targetClass: AnyClass, selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> HookToken { return try hookAfter(targetClass: targetClass, selector: selector, closure: closure as Any) } @@ -81,7 +81,7 @@ public func hookAfter(targetClass: AnyClass, selector: Selector, closure: @escap print("hooked") }) _ = MyObject().sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter targetClass: The class you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -89,7 +89,7 @@ public func hookAfter(targetClass: AnyClass, selector: Selector, closure: @escap - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookBefore(targetClass: T.Type, selector: Selector, closure: @escaping (_ object: T, _ selector: Selector) -> Void) throws -> Token { +public func hookBefore(targetClass: T.Type, selector: Selector, closure: @escaping (_ object: T, _ selector: Selector) -> Void) throws -> HookToken { let closure = { obj, sel in guard let obj = obj as? T else { fatalError() } closure(obj, sel) @@ -112,7 +112,7 @@ public func hookBefore(targetClass: T.Type, selector: Selector, cl print("hooked") }) _ = MyObject().sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter targetClass: The class you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -120,7 +120,7 @@ public func hookBefore(targetClass: T.Type, selector: Selector, cl - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookAfter(targetClass: T.Type, selector: Selector, closure: @escaping (_ object: T, _ selector: Selector) -> Void) throws -> Token { +public func hookAfter(targetClass: T.Type, selector: Selector, closure: @escaping (_ object: T, _ selector: Selector) -> Void) throws -> HookToken { let closure = { obj, sel in guard let obj = obj as? T else { fatalError() } closure(obj, sel) @@ -145,7 +145,7 @@ public func hookAfter(targetClass: T.Type, selector: Selector, clo print("hooked") } as @convention(block) (AnyObject, Selector, Int, Int) -> Void) _ = MyObject().sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter targetClass: The class you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -158,11 +158,8 @@ public func hookAfter(targetClass: T.Type, selector: Selector, clo - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookBefore(targetClass: AnyClass, selector: Selector, closure: Any) throws -> Token { - return try swiftHookSerialQueue.sync { () -> Token in - try parametersCheck(targetClass: targetClass, selector: selector, mode: .before, closure: closure as AnyObject) - return try internalHook(targetClass: targetClass, selector: selector, mode: .before, hookClosure: closure as AnyObject) - } +public func hookBefore(targetClass: AnyClass, selector: Selector, closure: Any) throws -> HookToken { + return try internalHook(targetClass: targetClass, selector: selector, mode: .before, hookClosure: closure as AnyObject) } // after @@ -180,7 +177,7 @@ public func hookBefore(targetClass: AnyClass, selector: Selector, closure: Any) print("hooked") } as @convention(block) (AnyObject, Selector, Int, Int) -> Void) _ = MyObject().sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter targetClass: The class you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -193,11 +190,8 @@ public func hookBefore(targetClass: AnyClass, selector: Selector, closure: Any) - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookAfter(targetClass: AnyClass, selector: Selector, closure: Any) throws -> Token { - return try swiftHookSerialQueue.sync { () -> Token in - try parametersCheck(targetClass: targetClass, selector: selector, mode: .after, closure: closure as AnyObject) - return try internalHook(targetClass: targetClass, selector: selector, mode: .after, hookClosure: closure as AnyObject) - } +public func hookAfter(targetClass: AnyClass, selector: Selector, closure: Any) throws -> HookToken { + return try internalHook(targetClass: targetClass, selector: selector, mode: .after, hookClosure: closure as AnyObject) } // instead @@ -216,7 +210,7 @@ public func hookAfter(targetClass: AnyClass, selector: Selector, closure: Any) t return original(obj, sel, number1, numebr2) } as @convention(block) ((AnyObject, Selector, Int, Int) -> Int, AnyObject, Selector, Int, Int) -> Int ) _ = MyObject().sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter targetClass: The class you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -230,11 +224,8 @@ public func hookAfter(targetClass: AnyClass, selector: Selector, closure: Any) t - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookInstead(targetClass: AnyClass, selector: Selector, closure: Any) throws -> Token { - return try swiftHookSerialQueue.sync { () -> Token in - try parametersCheck(targetClass: targetClass, selector: selector, mode: .instead, closure: closure as AnyObject) - return try internalHook(targetClass: targetClass, selector: selector, mode: .instead, hookClosure: closure as AnyObject) - } +public func hookInstead(targetClass: AnyClass, selector: Selector, closure: Any) throws -> HookToken { + return try internalHook(targetClass: targetClass, selector: selector, mode: .instead, hookClosure: closure as AnyObject) } // MARK: before deinit @@ -252,18 +243,15 @@ public func hookInstead(targetClass: AnyClass, selector: Selector, closure: Any) autoreleasepool { let object = MyObject() } - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter targetClass: The class you want to hook on. It has to be inherited from NSObject. - parameter closure: The hook closure. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookDeallocBefore(targetClass: NSObject.Type, closure: @escaping @convention(block) () -> Void) throws -> Token { - return try swiftHookSerialQueue.sync { () -> Token in - try parametersCheck(targetClass: targetClass, selector: deallocSelector, mode: .before, closure: closure as AnyObject) - return try internalHook(targetClass: targetClass, selector: deallocSelector, mode: .before, hookClosure: closure as AnyObject) - } +public func hookDeallocBefore(targetClass: NSObject.Type, closure: @escaping @convention(block) () -> Void) throws -> HookToken { + return try internalHook(targetClass: targetClass, selector: deallocSelector, mode: .before, hookClosure: closure as AnyObject) } /** @@ -279,7 +267,7 @@ public func hookDeallocBefore(targetClass: NSObject.Type, closure: @escaping @co autoreleasepool { let object = MyObject() } - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter targetClass: The class you want to hook on. It has to be inherited from NSObject. - parameter closure: The hook closure. @@ -291,15 +279,12 @@ public func hookDeallocBefore(targetClass: NSObject.Type, closure: @escaping @co - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookDeallocBefore(targetClass: T.Type, closure: @escaping (_ object: T) -> Void) throws -> Token { +public func hookDeallocBefore(targetClass: T.Type, closure: @escaping (_ object: T) -> Void) throws -> HookToken { let closure = { obj in guard let obj = obj as? T else { fatalError() } closure(obj) } as @convention(block) (NSObject) -> Void - return try swiftHookSerialQueue.sync { () -> Token in - try parametersCheck(targetClass: targetClass, selector: deallocSelector, mode: .before, closure: closure as AnyObject) - return try internalHook(targetClass: targetClass, selector: deallocSelector, mode: .before, hookClosure: closure as AnyObject) - } + return try internalHook(targetClass: targetClass, selector: deallocSelector, mode: .before, hookClosure: closure as AnyObject) } // MARK: after deinit @@ -317,18 +302,15 @@ public func hookDeallocBefore(targetClass: T.Type, closure: @escapi autoreleasepool { let object = MyObject() } - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter targetClass: The class you want to hook on. It has to be inherited from NSObject. - parameter closure: The hook closure. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookDeallocAfter(targetClass: NSObject.Type, closure: @escaping @convention(block) () -> Void) throws -> Token { - return try swiftHookSerialQueue.sync { () -> Token in - try parametersCheck(targetClass: targetClass, selector: deallocSelector, mode: .after, closure: closure as AnyObject) - return try internalHook(targetClass: targetClass, selector: deallocSelector, mode: .after, hookClosure: closure as AnyObject) - } +public func hookDeallocAfter(targetClass: NSObject.Type, closure: @escaping @convention(block) () -> Void) throws -> HookToken { + return try internalHook(targetClass: targetClass, selector: deallocSelector, mode: .after, hookClosure: closure as AnyObject) } // MARK: replace deinit @@ -348,7 +330,7 @@ public func hookDeallocAfter(targetClass: NSObject.Type, closure: @escaping @con autoreleasepool { let object = MyObject() } - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter targetClass: The class you want to hook on. It has to be inherited from NSObject. - parameter closure: The hook closure. @@ -360,9 +342,6 @@ public func hookDeallocAfter(targetClass: NSObject.Type, closure: @escaping @con - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookDeallocInstead(targetClass: NSObject.Type, closure: @escaping @convention(block) (_ original: () -> Void) -> Void) throws -> Token { - try swiftHookSerialQueue.sync { () -> Token in - try parametersCheck(targetClass: targetClass, selector: deallocSelector, mode: .instead, closure: closure as AnyObject) - return try internalHook(targetClass: targetClass, selector: deallocSelector, mode: .instead, hookClosure: closure as AnyObject) - } +public func hookDeallocInstead(targetClass: NSObject.Type, closure: @escaping @convention(block) (_ original: () -> Void) -> Void) throws -> HookToken { + return try internalHook(targetClass: targetClass, selector: deallocSelector, mode: .instead, hookClosure: closure as AnyObject) } diff --git a/SwiftHook/Classes/Public/HookClassMethods.swift b/SwiftHook/Classes/Public/HookClassMethods.swift index 63cd30e5..d6a40a22 100644 --- a/SwiftHook/Classes/Public/HookClassMethods.swift +++ b/SwiftHook/Classes/Public/HookClassMethods.swift @@ -25,7 +25,7 @@ import Foundation print("hooked") }) _ = MyObject.sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter targetClass: The class you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -33,7 +33,7 @@ import Foundation - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookClassMethodBefore(targetClass: AnyClass, selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> Token { +public func hookClassMethodBefore(targetClass: AnyClass, selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> HookToken { return try hookClassMethodBefore(targetClass: targetClass, selector: selector, closure: closure as Any) } @@ -52,7 +52,7 @@ public func hookClassMethodBefore(targetClass: AnyClass, selector: Selector, clo print("hooked") }) _ = MyObject.sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter targetClass: The class you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -60,7 +60,7 @@ public func hookClassMethodBefore(targetClass: AnyClass, selector: Selector, clo - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookClassMethodAfter(targetClass: AnyClass, selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> Token { +public func hookClassMethodAfter(targetClass: AnyClass, selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> HookToken { return try hookClassMethodAfter(targetClass: targetClass, selector: selector, closure: closure as Any) } @@ -81,7 +81,7 @@ public func hookClassMethodAfter(targetClass: AnyClass, selector: Selector, clos print("hooked") }) _ = MyObject.sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter targetClass: The class you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -89,7 +89,7 @@ public func hookClassMethodAfter(targetClass: AnyClass, selector: Selector, clos - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookClassMethodBefore(targetClass: T.Type, selector: Selector, closure: @escaping (_ class: T.Type, _ selector: Selector) -> Void) throws -> Token { +public func hookClassMethodBefore(targetClass: T.Type, selector: Selector, closure: @escaping (_ class: T.Type, _ selector: Selector) -> Void) throws -> HookToken { let closure = { obj, sel in guard let obj = obj as? T.Type else { fatalError() } closure(obj, sel) @@ -112,7 +112,7 @@ public func hookClassMethodBefore(targetClass: T.Type, selector: S print("hooked") }) _ = MyObject.sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter targetClass: The class you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -120,7 +120,7 @@ public func hookClassMethodBefore(targetClass: T.Type, selector: S - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookClassMethodAfter(targetClass: T.Type, selector: Selector, closure: @escaping (_ class: T.Type, _ selector: Selector) -> Void) throws -> Token { +public func hookClassMethodAfter(targetClass: T.Type, selector: Selector, closure: @escaping (_ class: T.Type, _ selector: Selector) -> Void) throws -> HookToken { let closure = { obj, sel in guard let obj = obj as? T.Type else { fatalError() } closure(obj, sel) @@ -145,7 +145,7 @@ public func hookClassMethodAfter(targetClass: T.Type, selector: Se print("hooked") } as @convention(block) (AnyObject, Selector, Int, Int) -> Void) _ = MyObject.sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter targetClass: The class you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -158,14 +158,11 @@ public func hookClassMethodAfter(targetClass: T.Type, selector: Se - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookClassMethodBefore(targetClass: AnyClass, selector: Selector, closure: Any) throws -> Token { +public func hookClassMethodBefore(targetClass: AnyClass, selector: Selector, closure: Any) throws -> HookToken { guard let targetClass = object_getClass(targetClass) else { throw SwiftHookError.internalError(file: #file, line: #line) } - return try swiftHookSerialQueue.sync { - try parametersCheck(targetClass: targetClass, selector: selector, mode: .before, closure: closure as AnyObject) - return try internalHook(targetClass: targetClass, selector: selector, mode: .before, hookClosure: closure as AnyObject) - } + return try internalHook(targetClass: targetClass, selector: selector, mode: .before, hookClosure: closure as AnyObject) } // after @@ -183,7 +180,7 @@ public func hookClassMethodBefore(targetClass: AnyClass, selector: Selector, clo print("hooked") } as @convention(block) (AnyObject, Selector, Int, Int) -> Void) _ = MyObject.sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter targetClass: The class you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -196,14 +193,11 @@ public func hookClassMethodBefore(targetClass: AnyClass, selector: Selector, clo - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookClassMethodAfter(targetClass: AnyClass, selector: Selector, closure: Any) throws -> Token { +public func hookClassMethodAfter(targetClass: AnyClass, selector: Selector, closure: Any) throws -> HookToken { guard let targetClass = object_getClass(targetClass) else { throw SwiftHookError.internalError(file: #file, line: #line) } - return try swiftHookSerialQueue.sync { - try parametersCheck(targetClass: targetClass, selector: selector, mode: .after, closure: closure as AnyObject) - return try internalHook(targetClass: targetClass, selector: selector, mode: .after, hookClosure: closure as AnyObject) - } + return try internalHook(targetClass: targetClass, selector: selector, mode: .after, hookClosure: closure as AnyObject) } // instead @@ -222,7 +216,7 @@ public func hookClassMethodAfter(targetClass: AnyClass, selector: Selector, clos return original(obj, sel, number1, numebr2) } as @convention(block) ((AnyObject, Selector, Int, Int) -> Int, AnyObject, Selector, Int, Int) -> Int ) _ = MyObject.sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter targetClass: The class you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -236,12 +230,9 @@ public func hookClassMethodAfter(targetClass: AnyClass, selector: Selector, clos - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookClassMethodInstead(targetClass: AnyClass, selector: Selector, closure: Any) throws -> Token { +public func hookClassMethodInstead(targetClass: AnyClass, selector: Selector, closure: Any) throws -> HookToken { guard let targetClass = object_getClass(targetClass) else { throw SwiftHookError.internalError(file: #file, line: #line) } - return try swiftHookSerialQueue.sync { - try parametersCheck(targetClass: targetClass, selector: selector, mode: .instead, closure: closure as AnyObject) - return try internalHook(targetClass: targetClass, selector: selector, mode: .instead, hookClosure: closure as AnyObject) - } + return try internalHook(targetClass: targetClass, selector: selector, mode: .instead, hookClosure: closure as AnyObject) } diff --git a/SwiftHook/Classes/Public/HookCommon.swift b/SwiftHook/Classes/Public/HookCommon.swift index d913764f..99b856f3 100644 --- a/SwiftHook/Classes/Public/HookCommon.swift +++ b/SwiftHook/Classes/Public/HookCommon.swift @@ -41,29 +41,3 @@ public enum SwiftHookError: Error { case hookKVOUnsupportedInstance // Unable to hook a instance which is not support KVO. } - -// MARK: - Token -public protocol Token { - func cancelHook() -} - -struct HookToken: Token { - - weak var hookContext: HookContext? - weak var hookClosure: AnyObject? - let mode: HookMode - - weak var hookObject: AnyObject? // This is only for specified instance hook - - init(hookContext: HookContext, hookClosure: AnyObject, mode: HookMode) { - self.hookContext = hookContext - self.hookClosure = hookClosure - self.mode = mode - } - - func cancelHook() { - swiftHookSerialQueue.sync { - _ = try? internalCancelHook(token: self) - } - } -} diff --git a/SwiftHook/Classes/Public/HookSpecificInstance.swift b/SwiftHook/Classes/Public/HookSpecificInstance.swift index 9a3f8ecf..b2d81088 100644 --- a/SwiftHook/Classes/Public/HookSpecificInstance.swift +++ b/SwiftHook/Classes/Public/HookSpecificInstance.swift @@ -26,7 +26,7 @@ import Foundation print("hooked") }) _ = object.sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter object: The object you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -34,7 +34,7 @@ import Foundation - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookBefore(object: AnyObject, selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> Token { +public func hookBefore(object: AnyObject, selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> HookToken { return try hookBefore(object: object, selector: selector, closure: closure as Any) } @@ -54,7 +54,7 @@ public func hookBefore(object: AnyObject, selector: Selector, closure: @escaping print("hooked") }) _ = object.sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter object: The object you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -62,7 +62,7 @@ public func hookBefore(object: AnyObject, selector: Selector, closure: @escaping - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookAfter(object: AnyObject, selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> Token { +public func hookAfter(object: AnyObject, selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> HookToken { return try hookAfter(object: object, selector: selector, closure: closure as Any) } @@ -84,7 +84,7 @@ public func hookAfter(object: AnyObject, selector: Selector, closure: @escaping print("hooked") }) _ = object.sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter object: The object you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -92,7 +92,7 @@ public func hookAfter(object: AnyObject, selector: Selector, closure: @escaping - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookBefore(object: T, selector: Selector, closure: @escaping (_ object: T, _ selector: Selector) -> Void) throws -> Token { +public func hookBefore(object: T, selector: Selector, closure: @escaping (_ object: T, _ selector: Selector) -> Void) throws -> HookToken { let closure = { obj, sel in guard let obj = obj as? T else { fatalError() } closure(obj, sel) @@ -116,7 +116,7 @@ public func hookBefore(object: T, selector: Selector, closure: @es print("hooked") }) _ = object.sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter object: The object you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -124,7 +124,7 @@ public func hookBefore(object: T, selector: Selector, closure: @es - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookAfter(object: T, selector: Selector, closure: @escaping (_ object: T, _ selector: Selector) -> Void) throws -> Token { +public func hookAfter(object: T, selector: Selector, closure: @escaping (_ object: T, _ selector: Selector) -> Void) throws -> HookToken { let closure = { obj, sel in guard let obj = obj as? T else { fatalError() } closure(obj, sel) @@ -150,7 +150,7 @@ public func hookAfter(object: T, selector: Selector, closure: @esc print("hooked") } as @convention(block) (AnyObject, Selector, Int, Int) -> Void) _ = object.sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter object: The object you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -163,11 +163,8 @@ public func hookAfter(object: T, selector: Selector, closure: @esc - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookBefore(object: AnyObject, selector: Selector, closure: Any) throws -> Token { - return try swiftHookSerialQueue.sync { () -> Token in - try parametersCheck(object: object, selector: selector, mode: .before, closure: closure as AnyObject) - return try internalHook(object: object, selector: selector, mode: .before, hookClosure: closure as AnyObject) - } +public func hookBefore(object: AnyObject, selector: Selector, closure: Any) throws -> HookToken { + return try internalHook(object: object, selector: selector, mode: .before, hookClosure: closure as AnyObject) } // after @@ -186,7 +183,7 @@ public func hookBefore(object: AnyObject, selector: Selector, closure: Any) thro print("hooked") } as @convention(block) (AnyObject, Selector, Int, Int) -> Void) _ = object.sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter object: The object you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -199,11 +196,8 @@ public func hookBefore(object: AnyObject, selector: Selector, closure: Any) thro - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookAfter(object: AnyObject, selector: Selector, closure: Any) throws -> Token { - return try swiftHookSerialQueue.sync { () -> Token in - try parametersCheck(object: object, selector: selector, mode: .after, closure: closure as AnyObject) - return try internalHook(object: object, selector: selector, mode: .after, hookClosure: closure as AnyObject) - } +public func hookAfter(object: AnyObject, selector: Selector, closure: Any) throws -> HookToken { + return try internalHook(object: object, selector: selector, mode: .after, hookClosure: closure as AnyObject) } // instead @@ -223,7 +217,7 @@ public func hookAfter(object: AnyObject, selector: Selector, closure: Any) throw return original(obj, sel, number1, numebr2) } as @convention(block) ((AnyObject, Selector, Int, Int) -> Int, AnyObject, Selector, Int, Int) -> Int ) _ = object.sum(1, 2) - token.cancelHook() // cancel hook + token.revert() // cancel hook ``` - parameter object: The object you want to hook on. It doesn’t have to be inherited from NSObject. - parameter selector: The method you want to hook on. It has to be declared with the keywords `@objc` and `dynamic`. @@ -237,11 +231,8 @@ public func hookAfter(object: AnyObject, selector: Selector, closure: Any) throw - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookInstead(object: AnyObject, selector: Selector, closure: Any) throws -> Token { - return try swiftHookSerialQueue.sync { - try parametersCheck(object: object, selector: selector, mode: .instead, closure: closure as AnyObject) - return try internalHook(object: object, selector: selector, mode: .instead, hookClosure: closure as AnyObject) - } +public func hookInstead(object: AnyObject, selector: Selector, closure: Any) throws -> HookToken { + return try internalHook(object: object, selector: selector, mode: .instead, hookClosure: closure as AnyObject) } // MARK: before deinit @@ -259,18 +250,15 @@ public func hookInstead(object: AnyObject, selector: Selector, closure: Any) thr print("hooked") }) } - token?.cancelHook() // cancel hook + token?.revert() // cancel hook ``` - parameter object: The object you want to hook on. It has to be inherited from NSObject. - parameter closure: The hook closure. **WARNING**: The object will retain the closure. So make sure that the closure doesn't retain the object in turn to avoid memory leak because of cycle retain. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookDeallocBefore(object: NSObject, closure: @escaping @convention(block) () -> Void) throws -> Token { - return try swiftHookSerialQueue.sync { () -> Token in - try parametersCheck(object: object, selector: deallocSelector, mode: .before, closure: closure as AnyObject) - return try internalHook(object: object, selector: deallocSelector, mode: .before, hookClosure: closure as AnyObject) - } +public func hookDeallocBefore(object: NSObject, closure: @escaping @convention(block) () -> Void) throws -> HookToken { + return try internalHook(object: object, selector: deallocSelector, mode: .before, hookClosure: closure as AnyObject) } /** @@ -287,7 +275,7 @@ public func hookDeallocBefore(object: NSObject, closure: @escaping @convention(b print("hooked") }) } - token?.cancelHook() // cancel hook + token?.revert() // cancel hook ``` - parameter object: The object you want to hook on. It has to be inherited from NSObject. - parameter closure: The hook closure. @@ -301,15 +289,12 @@ public func hookDeallocBefore(object: NSObject, closure: @escaping @convention(b - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookDeallocBefore(object: T, closure: @escaping (_ object: T) -> Void) throws -> Token { +public func hookDeallocBefore(object: T, closure: @escaping (_ object: T) -> Void) throws -> HookToken { let closure = { obj in guard let obj = obj as? T else { fatalError() } closure(obj) } as @convention(block) (NSObject) -> Void - return try swiftHookSerialQueue.sync { () -> Token in - try parametersCheck(object: object, selector: deallocSelector, mode: .before, closure: closure as AnyObject) - return try internalHook(object: object, selector: deallocSelector, mode: .before, hookClosure: closure as AnyObject) - } + return try internalHook(object: object, selector: deallocSelector, mode: .before, hookClosure: closure as AnyObject) } // MARK: after deinit @@ -328,18 +313,15 @@ public func hookDeallocBefore(object: T, closure: @escaping (_ obje print("hooked") }) } - token?.cancelHook() // cancel hook + token?.revert() // cancel hook ``` - parameter object: The object you want to hook on. It has to be inherited from NSObject. - parameter closure: The hook closure. **WARNING**: The object will retain the closure. So make sure that the closure doesn't retain the object in turn to avoid memory leak because of cycle retain. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookDeallocAfter(object: NSObject, closure: @escaping @convention(block) () -> Void) throws -> Token { - return try swiftHookSerialQueue.sync { () -> Token in - try parametersCheck(object: object, selector: deallocSelector, mode: .after, closure: closure as AnyObject) - return try internalHook(object: object, selector: deallocSelector, mode: .after, hookClosure: closure as AnyObject) - } +public func hookDeallocAfter(object: NSObject, closure: @escaping @convention(block) () -> Void) throws -> HookToken { + return try internalHook(object: object, selector: deallocSelector, mode: .after, hookClosure: closure as AnyObject) } /** @@ -356,17 +338,15 @@ public func hookDeallocAfter(object: NSObject, closure: @escaping @convention(bl print("hooked") }) } - token?.cancelHook() // cancel hook + token?.revert() // cancel hook ``` - parameter object: The object you want to hook on. It doesn’t have to be inherited from NSObject. - parameter closure: The hook closure. **WARNING**: The object will retain the closure. So make sure that the closure doesn't retain the object in turn to avoid memory leak because of cycle retain. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookDeallocAfterByTail(object: AnyObject, closure: @escaping @convention(block) () -> Void) -> Token { - return swiftHookSerialQueue.sync { - return hookDeallocAfterByDelegate(object: object, closure: closure as AnyObject) - } +public func hookDeallocAfterByTail(object: AnyObject, closure: @escaping @convention(block) () -> Void) -> HookToken { + return hookDeallocAfterByDelegate(object: object, closure: closure as AnyObject) } // MARK: replace deinit @@ -387,7 +367,7 @@ public func hookDeallocAfterByTail(object: AnyObject, closure: @escaping @conven print("after release") }) } - token?.cancelHook() // cancel hook + token?.revert() // cancel hook ``` - parameter object: The object you want to hook on. It has to be inherited from NSObject. - parameter closure: The hook closure. @@ -401,9 +381,6 @@ public func hookDeallocAfterByTail(object: AnyObject, closure: @escaping @conven - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult -public func hookDeallocInstead(object: NSObject, closure: @escaping @convention(block) (_ original: () -> Void) -> Void) throws -> Token { - try swiftHookSerialQueue.sync { () -> Token in - try parametersCheck(object: object, selector: deallocSelector, mode: .instead, closure: closure as AnyObject) - return try internalHook(object: object, selector: deallocSelector, mode: .instead, hookClosure: closure as AnyObject) - } +public func hookDeallocInstead(object: NSObject, closure: @escaping @convention(block) (_ original: () -> Void) -> Void) throws -> HookToken { + return try internalHook(object: object, selector: deallocSelector, mode: .instead, hookClosure: closure as AnyObject) } diff --git a/SwiftHook/Classes/Public/HookToken.swift b/SwiftHook/Classes/Public/HookToken.swift new file mode 100644 index 00000000..c7ec2b76 --- /dev/null +++ b/SwiftHook/Classes/Public/HookToken.swift @@ -0,0 +1,124 @@ +// +// HookToken.swift +// SwiftHook +// +// Created by Florian Zand on 10.05.25. +// + +import Foundation + +/// Represents a hook to a method. +@objcMembers +public class HookToken: NSObject { + + let hookClosure: AnyObject + weak var hookObject: AnyObject? // This is only for specified instance hook + let targetClass: AnyClass? + var hooksDealloc = false + weak var deallocAfterDelegate: HookDeallocAfterDelegate? + weak var hookContext: HookContext? + + /// The hooking mode. + @objc public let mode: HookMode + + /// The selector of the hook. + @objc public let selector: Selector + + /// A Boolean value indicating whether the hook is active. + @objc public var isActive: Bool { + get { hookContext != nil || deallocAfterDelegate != nil } + set { _ = newValue ? apply() : revert() } + } + + /** + Applies the hook. + + - Returns: `true` if the hook is successfully applied, otherwise `false`. + */ + @discardableResult + @objc public func apply() -> Bool { + guard !isActive else { + return true + } + return swiftHookSerialQueue.sync { + if !hooksDealloc { + try? internalApplyHook(token: self) + return isActive + } else if let object = hookObject { + var delegate: HookDeallocAfterDelegate! = objc_getAssociatedObject(object, &associatedDelegateHandle) as? HookDeallocAfterDelegate + if delegate == nil { + delegate = HookDeallocAfterDelegate() + objc_setAssociatedObject(object, &associatedDelegateHandle, delegate, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + deallocAfterDelegate = delegate + deallocAfterDelegate?.hookClosures.append(hookClosure) + return true + } + return false + } + } + + /** + Reverts the hook. + + - Returns: `true` if the hook is successfully reverted, otherwise `false`. + */ + @discardableResult + @objc public func revert() -> Bool { + guard isActive else { + return true + } + return swiftHookSerialQueue.sync { + if hooksDealloc { + deallocAfterDelegate?.hookClosures.removeAll(where: { $0 === self.hookClosure }) + deallocAfterDelegate = nil + return true + } else { + _ = try? internalCancelHook(token: self) + return !isActive + } + } + } + + init(object: AnyObject, selector: Selector, mode: HookMode, hookClosure: AnyObject) throws { + try swiftHookSerialQueue.sync { + try parametersCheck(object: object, selector: deallocSelector, mode: .instead, closure: hookClosure) + } + self.hookObject = object + self.targetClass = nil + self.mode = mode + self.selector = selector + self.hookClosure = hookClosure + } + + init(targetClass: AnyClass, selector: Selector, mode: HookMode, hookClosure: AnyObject) throws { + try swiftHookSerialQueue.sync { + try parametersCheck(targetClass: targetClass, selector: deallocSelector, mode: .instead, closure: hookClosure) + } + self.targetClass = targetClass + self.mode = mode + self.selector = selector + self.hookClosure = hookClosure + } + + init(deallocAfter object: AnyObject, hookClosure: AnyObject) { + self.targetClass = nil + self.hookObject = object + self.mode = .after + self.selector = deallocSelector + self.hookClosure = hookClosure + self.hooksDealloc = true + } + + class HookDeallocAfterDelegate { + var hookClosures = [AnyObject]() + + deinit { + for item in hookClosures.reversed() { + unsafeBitCast(item, to: (@convention(block) () -> Void).self)() + } + } + } +} + +private var associatedDelegateHandle: UInt8 = 0 diff --git a/SwiftHook/Classes/PublicObjectiveCAPI/HookAllInstancesOC.swift b/SwiftHook/Classes/PublicObjectiveCAPI/HookAllInstancesOC.swift index dc5a2fc0..68cec834 100644 --- a/SwiftHook/Classes/PublicObjectiveCAPI/HookAllInstancesOC.swift +++ b/SwiftHook/Classes/PublicObjectiveCAPI/HookAllInstancesOC.swift @@ -28,18 +28,18 @@ public extension NSObject { ``` # Example to use the API ``` - OCToken *token = [MyObject sh_hookBeforeSelector:@selector(sumWithNumber1:number2:) error:NULL closure:^{ + HookToken *token = [MyObject sh_hookBeforeSelector:@selector(sumWithNumber1:number2:) error:NULL closure:^{ NSLog(@"hooked"); }]; [[[MyObject alloc] init] sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closure: The hook closure. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc class func sh_hookBefore(selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> OCToken { + @objc class func sh_hookBefore(selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> HookToken { return try self.sh_hookBefore(selector: selector, closure: closure as Any) } @@ -59,18 +59,18 @@ public extension NSObject { ``` # Example to use the API ``` - OCToken *token = [MyObject sh_hookAfterSelector:@selector(sumWithNumber1:number2:) error:NULL closure:^{ + HookToken *token = [MyObject sh_hookAfterSelector:@selector(sumWithNumber1:number2:) error:NULL closure:^{ NSLog(@"hooked"); }]; [[[MyObject alloc] init] sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closure: The hook closure. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc class func sh_hookAfter(selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> OCToken { + @objc class func sh_hookAfter(selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> HookToken { return try self.sh_hookAfter(selector: selector, closure: closure as Any) } @@ -92,18 +92,18 @@ public extension NSObject { ``` # Example to use the API ``` - OCToken *token = [MyObject sh_hookBeforeSelector:@selector(sumWithNumber1:number2:) error:NULL closureObjSel:^(NSObject * _Nonnull obj, SEL _Nonnull sel) { + HookToken *token = [MyObject sh_hookBeforeSelector:@selector(sumWithNumber1:number2:) error:NULL closureObjSel:^(NSObject * _Nonnull obj, SEL _Nonnull sel) { NSLog(@"hooked"); }]; [[[MyObject alloc] init] sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closureObjSel: The hook closure. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc class func sh_hookBefore(selector: Selector, closureObjSel: @escaping @convention(block) (_ object: NSObject, _ selector: Selector) -> Void) throws -> OCToken { + @objc class func sh_hookBefore(selector: Selector, closureObjSel: @escaping @convention(block) (_ object: NSObject, _ selector: Selector) -> Void) throws -> HookToken { return try self.sh_hookBefore(selector: selector, closure: closureObjSel as Any) } @@ -123,18 +123,18 @@ public extension NSObject { ``` # Example to use the API ``` - OCToken *token = [MyObject sh_hookAfterSelector:@selector(sumWithNumber1:number2:) error:NULL closureObjSel:^(NSObject * _Nonnull obj, SEL _Nonnull sel) { + HookToken *token = [MyObject sh_hookAfterSelector:@selector(sumWithNumber1:number2:) error:NULL closureObjSel:^(NSObject * _Nonnull obj, SEL _Nonnull sel) { NSLog(@"hooked"); }]; [[[MyObject alloc] init] sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closureObjSel: The hook closure. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc class func sh_hookAfter(selector: Selector, closureObjSel: @escaping @convention(block) (_ object: NSObject, _ selector: Selector) -> Void) throws -> OCToken { + @objc class func sh_hookAfter(selector: Selector, closureObjSel: @escaping @convention(block) (_ object: NSObject, _ selector: Selector) -> Void) throws -> HookToken { return try self.sh_hookAfter(selector: selector, closure: closureObjSel as Any) } @@ -156,11 +156,11 @@ public extension NSObject { ``` # Example to use the API ``` - OCToken *token = [MyObject sh_hookBeforeSelector:@selector(sumWithNumber1:number2:) closure:^(MyObject * _Nonnull obj, SEL _Nonnull sel, NSInteger number1, NSInteger number2){ + HookToken *token = [MyObject sh_hookBeforeSelector:@selector(sumWithNumber1:number2:) closure:^(MyObject * _Nonnull obj, SEL _Nonnull sel, NSInteger number1, NSInteger number2){ NSLog(@"hooked"); } error:NULL]; [[[MyObject alloc] init] sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closure: The hook closure. The following is a description of the closure @@ -171,9 +171,9 @@ public extension NSObject { - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc class func sh_hookBefore(selector: Selector, closure: Any) throws -> OCToken { + @objc class func sh_hookBefore(selector: Selector, closure: Any) throws -> HookToken { do { - return OCToken(token: try hookBefore(targetClass: self, selector: selector, closure: closure)) + return try hookBefore(targetClass: self, selector: selector, closure: closure) } catch { guard let swiftHookError = error as? SwiftHookError else { throw error @@ -198,11 +198,11 @@ public extension NSObject { ``` # Example to use the API ``` - OCToken *token = [MyObject sh_hookAfterSelector:@selector(sumWithNumber1:number2:) closure:^(MyObject * _Nonnull obj, SEL _Nonnull sel, NSInteger number1, NSInteger number2){ + HookToken *token = [MyObject sh_hookAfterSelector:@selector(sumWithNumber1:number2:) closure:^(MyObject * _Nonnull obj, SEL _Nonnull sel, NSInteger number1, NSInteger number2){ NSLog(@"hooked"); } error:NULL]; [[[MyObject alloc] init] sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closure: The hook closure. The following is a description of the closure @@ -213,9 +213,9 @@ public extension NSObject { - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc class func sh_hookAfter(selector: Selector, closure: Any) throws -> OCToken { + @objc class func sh_hookAfter(selector: Selector, closure: Any) throws -> HookToken { do { - return OCToken(token: try hookAfter(targetClass: self, selector: selector, closure: closure)) + return try hookAfter(targetClass: self, selector: selector, closure: closure) } catch { guard let swiftHookError = error as? SwiftHookError else { throw error @@ -240,13 +240,13 @@ public extension NSObject { ``` # Example to use the API ``` - OCToken *token = [MyObject sh_hookInsteadWithSelector:@selector(sumWithNumber1:number2:) closure:^NSInteger(NSInteger(^original)(MyObject * _Nonnull obj, SEL _Nonnull sel, NSInteger number1, NSInteger number2), MyObject * _Nonnull obj, SEL _Nonnull sel, NSInteger number1, NSInteger number2) { + HookToken *token = [MyObject sh_hookInsteadWithSelector:@selector(sumWithNumber1:number2:) closure:^NSInteger(NSInteger(^original)(MyObject * _Nonnull obj, SEL _Nonnull sel, NSInteger number1, NSInteger number2), MyObject * _Nonnull obj, SEL _Nonnull sel, NSInteger number1, NSInteger number2) { NSLog(@"hooked"); // You may call the original method with some different parameters. You can even not call the original method. return original(obj, sel, number1, number2); } error:NULL]; [[[MyObject alloc] init] sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closure: The hook closure. The following is a description of the closure @@ -258,9 +258,9 @@ public extension NSObject { - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc class func sh_hookInstead(selector: Selector, closure: Any) throws -> OCToken { + @objc class func sh_hookInstead(selector: Selector, closure: Any) throws -> HookToken { do { - return OCToken(token: try hookInstead(targetClass: self, selector: selector, closure: closure)) + return try hookInstead(targetClass: self, selector: selector, closure: closure) } catch { guard let swiftHookError = error as? SwiftHookError else { throw error @@ -275,21 +275,21 @@ public extension NSObject { # Example ``` - OCToken *token = [MyObject sh_hookDeallocBeforeAndReturnError:NULL closure:^{ + HookToken *token = [MyObject sh_hookDeallocBeforeAndReturnError:NULL closure:^{ NSLog(@"hooked"); }]; @autoreleasepool { MyObject *obj = [[MyObject alloc] init]; } - [token cancelHook]; + [token revert]; ``` - parameter closure: The hook closure. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc class func sh_hookDeallocBefore(closure: @escaping @convention(block) () -> Void) throws -> OCToken { + @objc class func sh_hookDeallocBefore(closure: @escaping @convention(block) () -> Void) throws -> HookToken { do { - return OCToken(token: try hookDeallocBefore(targetClass: self, closure: closure)) + return try hookDeallocBefore(targetClass: self, closure: closure) } catch { guard let swiftHookError = error as? SwiftHookError else { throw error @@ -303,13 +303,13 @@ public extension NSObject { # Example ``` - OCToken *token = [MyObject sh_hookDeallocBeforeAndReturnError:NULL closureObj:^(NSObject * _Nonnull obj) { + HookToken *token = [MyObject sh_hookDeallocBeforeAndReturnError:NULL closureObj:^(NSObject * _Nonnull obj) { NSLog(@"hooked"); }]; @autoreleasepool { MyObject *obj = [[MyObject alloc] init]; } - [token cancelHook]; + [token revert]; ``` - parameter closureObj: The hook closure. @@ -320,9 +320,9 @@ public extension NSObject { - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc class func sh_hookDeallocBefore(closureObj: @escaping @convention(block) (_ object: NSObject) -> Void) throws -> OCToken { + @objc class func sh_hookDeallocBefore(closureObj: @escaping @convention(block) (_ object: NSObject) -> Void) throws -> HookToken { do { - return OCToken(token: try hookDeallocBefore(targetClass: self, closure: closureObj)) + return try hookDeallocBefore(targetClass: self, closure: closureObj) } catch { guard let swiftHookError = error as? SwiftHookError else { throw error @@ -337,21 +337,21 @@ public extension NSObject { # Example ``` - OCToken *token = [MyObject sh_hookDeallocAfterAndReturnError:NULL closure:^{ + HookToken *token = [MyObject sh_hookDeallocAfterAndReturnError:NULL closure:^{ NSLog(@"hooked"); }]; @autoreleasepool { MyObject *obj = [[MyObject alloc] init]; } - [token cancelHook]; + [token revert]; ``` - parameter closure: The hook closure. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc class func sh_hookDeallocAfter(closure: @escaping @convention(block) () -> Void) throws -> OCToken { + @objc class func sh_hookDeallocAfter(closure: @escaping @convention(block) () -> Void) throws -> HookToken { do { - return OCToken(token: try hookDeallocAfter(targetClass: self, closure: closure)) + return try hookDeallocAfter(targetClass: self, closure: closure) } catch { guard let swiftHookError = error as? SwiftHookError else { throw error @@ -366,7 +366,7 @@ public extension NSObject { # Example ``` - OCToken *token = [MyObject sh_hookDeallocInsteadAndReturnError:NULL closure:^(void (^ _Nonnull original)(void)) { + HookToken *token = [MyObject sh_hookDeallocInsteadAndReturnError:NULL closure:^(void (^ _Nonnull original)(void)) { NSLog(@"before release"); original(); NSLog(@"after release"); @@ -374,7 +374,7 @@ public extension NSObject { @autoreleasepool { MyObject *obj = [[MyObject alloc] init]; } - [token cancelHook]; + [token revert]; ``` - parameter closure: The hook closure. @@ -383,9 +383,9 @@ public extension NSObject { - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc class func sh_hookDeallocInstead(closure: @escaping @convention(block) (_ original: () -> Void) -> Void) throws -> OCToken { + @objc class func sh_hookDeallocInstead(closure: @escaping @convention(block) (_ original: () -> Void) -> Void) throws -> HookToken { do { - return OCToken(token: try hookDeallocInstead(targetClass: self, closure: closure)) + return try hookDeallocInstead(targetClass: self, closure: closure) } catch { guard let swiftHookError = error as? SwiftHookError else { throw error diff --git a/SwiftHook/Classes/PublicObjectiveCAPI/HookClassMethodsOC.swift b/SwiftHook/Classes/PublicObjectiveCAPI/HookClassMethodsOC.swift index 43e8c4d9..aabd2e94 100644 --- a/SwiftHook/Classes/PublicObjectiveCAPI/HookClassMethodsOC.swift +++ b/SwiftHook/Classes/PublicObjectiveCAPI/HookClassMethodsOC.swift @@ -28,18 +28,18 @@ public extension NSObject { ``` # Example to use the API ``` - OCToken *token = [MyObject sh_hookClassMethodBeforeSelector:@selector(sumWithNumber1:number2:) error:NULL closure:^{ + HookToken *token = [MyObject sh_hookClassMethodBeforeSelector:@selector(sumWithNumber1:number2:) error:NULL closure:^{ NSLog(@"hooked"); }]; [MyObject sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closure: The hook closure. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc class func sh_hookClassMethodBefore(selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> OCToken { + @objc class func sh_hookClassMethodBefore(selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> HookToken { return try self.sh_hookClassMethodBefore(selector: selector, closure: closure as Any) } @@ -59,18 +59,18 @@ public extension NSObject { ``` # Example to use the API ``` - OCToken *token = [MyObject sh_hookClassMethodAfterSelector:@selector(sumWithNumber1:number2:) error:NULL closure:^{ + HookToken *token = [MyObject sh_hookClassMethodAfterSelector:@selector(sumWithNumber1:number2:) error:NULL closure:^{ NSLog(@"hooked"); }]; [MyObject sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closure: The hook closure. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc class func sh_hookClassMethodAfter(selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> OCToken { + @objc class func sh_hookClassMethodAfter(selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> HookToken { return try self.sh_hookClassMethodAfter(selector: selector, closure: closure as Any) } @@ -92,18 +92,18 @@ public extension NSObject { ``` # Example to use the API ``` - OCToken *token = [MyObject sh_hookClassMethodBeforeSelector:@selector(sumWithNumber1:number2:) error:NULL closureObjSel:^(Class _Nonnull __unsafe_unretained obj, SEL _Nonnull sel) { + HookToken *token = [MyObject sh_hookClassMethodBeforeSelector:@selector(sumWithNumber1:number2:) error:NULL closureObjSel:^(Class _Nonnull __unsafe_unretained obj, SEL _Nonnull sel) { NSLog(@"hooked"); }]; [MyObject sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closureObjSel: The hook closure. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc class func sh_hookClassMethodBefore(selector: Selector, closureObjSel: @escaping (_ class: AnyClass, _ selector: Selector) -> Void) throws -> OCToken { + @objc class func sh_hookClassMethodBefore(selector: Selector, closureObjSel: @escaping (_ class: AnyClass, _ selector: Selector) -> Void) throws -> HookToken { let closureObjSel = { obj, sel in guard let obj = obj as? AnyClass else { fatalError() } closureObjSel(obj, sel) @@ -127,18 +127,18 @@ public extension NSObject { ``` # Example to use the API ``` - OCToken *token = [MyObject sh_hookClassMethodAfterSelector:@selector(sumWithNumber1:number2:) error:NULL closureObjSel:^(Class _Nonnull __unsafe_unretained obj, SEL _Nonnull sel) { + HookToken *token = [MyObject sh_hookClassMethodAfterSelector:@selector(sumWithNumber1:number2:) error:NULL closureObjSel:^(Class _Nonnull __unsafe_unretained obj, SEL _Nonnull sel) { NSLog(@"hooked"); }]; [MyObject sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closureObjSel: The hook closure. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc class func sh_hookClassMethodAfter(selector: Selector, closureObjSel: @escaping (_ class: AnyClass, _ selector: Selector) -> Void) throws -> OCToken { + @objc class func sh_hookClassMethodAfter(selector: Selector, closureObjSel: @escaping (_ class: AnyClass, _ selector: Selector) -> Void) throws -> HookToken { let closureObjSel = { obj, sel in guard let obj = obj as? AnyClass else { fatalError() } closureObjSel(obj, sel) @@ -164,11 +164,11 @@ public extension NSObject { ``` # Example to use the API ``` - OCToken *token = [MyObject sh_hookClassMethodBeforeSelector:@selector(sumWithNumber1:number2:) closure:^(NSObject *obj, SEL sel, NSInteger number1, NSInteger number2) { + HookToken *token = [MyObject sh_hookClassMethodBeforeSelector:@selector(sumWithNumber1:number2:) closure:^(NSObject *obj, SEL sel, NSInteger number1, NSInteger number2) { NSLog(@"hooked"); } error:NULL]; [MyObject sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closure: The hook closure. The following is a description of the closure @@ -179,9 +179,9 @@ public extension NSObject { - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc class func sh_hookClassMethodBefore(selector: Selector, closure: Any) throws -> OCToken { + @objc class func sh_hookClassMethodBefore(selector: Selector, closure: Any) throws -> HookToken { do { - return OCToken(token: try hookClassMethodBefore(targetClass: self, selector: selector, closure: closure)) + return try hookClassMethodBefore(targetClass: self, selector: selector, closure: closure) } catch { guard let swiftHookError = error as? SwiftHookError else { throw error @@ -206,11 +206,11 @@ public extension NSObject { ``` # Example to use the API ``` - OCToken *token = [MyObject sh_hookClassMethodAfterSelector:@selector(sumWithNumber1:number2:) closure:^(NSObject *obj, SEL sel, NSInteger number1, NSInteger number2) { + HookToken *token = [MyObject sh_hookClassMethodAfterSelector:@selector(sumWithNumber1:number2:) closure:^(NSObject *obj, SEL sel, NSInteger number1, NSInteger number2) { NSLog(@"hooked"); } error:NULL]; [MyObject sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closure: The hook closure. The following is a description of the closure @@ -221,9 +221,9 @@ public extension NSObject { - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc class func sh_hookClassMethodAfter(selector: Selector, closure: Any) throws -> OCToken { + @objc class func sh_hookClassMethodAfter(selector: Selector, closure: Any) throws -> HookToken { do { - return OCToken(token: try hookClassMethodAfter(targetClass: self, selector: selector, closure: closure)) + return try hookClassMethodAfter(targetClass: self, selector: selector, closure: closure) } catch { guard let swiftHookError = error as? SwiftHookError else { throw error @@ -248,12 +248,12 @@ public extension NSObject { ``` # Example to use the API ``` - OCToken *token = [MyObject sh_hookClassMethodInsteadWithSelector:@selector(sumWithNumber1:number2:) closure:^NSInteger(NSInteger(^original)(NSObject *obj, SEL sel, NSInteger number1, NSInteger number2), NSObject *obj, SEL sel, NSInteger number1, NSInteger number2) { + HookToken *token = [MyObject sh_hookClassMethodInsteadWithSelector:@selector(sumWithNumber1:number2:) closure:^NSInteger(NSInteger(^original)(NSObject *obj, SEL sel, NSInteger number1, NSInteger number2), NSObject *obj, SEL sel, NSInteger number1, NSInteger number2) { NSLog(@"hooked"); return original(obj, sel, number1, number2); } error:NULL]; [MyObject sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closure: The hook closure. The following is a description of the closure @@ -265,9 +265,9 @@ public extension NSObject { - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc class func sh_hookClassMethodInstead(selector: Selector, closure: Any) throws -> OCToken { + @objc class func sh_hookClassMethodInstead(selector: Selector, closure: Any) throws -> HookToken { do { - return OCToken(token: try hookClassMethodInstead(targetClass: self, selector: selector, closure: closure)) + return try hookClassMethodInstead(targetClass: self, selector: selector, closure: closure) } catch { guard let swiftHookError = error as? SwiftHookError else { throw error diff --git a/SwiftHook/Classes/PublicObjectiveCAPI/HookCommonOC.swift b/SwiftHook/Classes/PublicObjectiveCAPI/HookCommonOC.swift index 9bb4131c..ace01c88 100644 --- a/SwiftHook/Classes/PublicObjectiveCAPI/HookCommonOC.swift +++ b/SwiftHook/Classes/PublicObjectiveCAPI/HookCommonOC.swift @@ -8,18 +8,6 @@ import Foundation -// MARK: - Token - -@objcMembers public class OCToken: NSObject { - private let token: Token - init(token: Token) { - self.token = token - } - public func cancelHook() { - token.cancelHook() - } -} - extension SwiftHookError { var getNSError: NSError { let code: Int diff --git a/SwiftHook/Classes/PublicObjectiveCAPI/HookSpecificInstanceOC.swift b/SwiftHook/Classes/PublicObjectiveCAPI/HookSpecificInstanceOC.swift index 885e2bb3..916ec8ae 100644 --- a/SwiftHook/Classes/PublicObjectiveCAPI/HookSpecificInstanceOC.swift +++ b/SwiftHook/Classes/PublicObjectiveCAPI/HookSpecificInstanceOC.swift @@ -29,18 +29,18 @@ public extension NSObject { # Example to use the API ``` MyObject *obj = [[MyObject alloc] init]; - OCToken *token = [obj sh_hookBeforeSelector:@selector(sumWithNumber1:number2:) error:NULL closure:^{ + HookToken *token = [obj sh_hookBeforeSelector:@selector(sumWithNumber1:number2:) error:NULL closure:^{ NSLog(@"hooked"); }]; [obj sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closure: The hook closure. **WARNING**: The object will retain the closure. So make sure that the closure doesn't retain the object in turn to avoid memory leak because of cycle retain. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc func sh_hookBefore(selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> OCToken { + @objc func sh_hookBefore(selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> HookToken { return try self.sh_hookBefore(selector: selector, closure: closure as Any) } @@ -61,18 +61,18 @@ public extension NSObject { # Example to use the API ``` MyObject *obj = [[MyObject alloc] init]; - OCToken *token = [obj sh_hookAfterSelector:@selector(sumWithNumber1:number2:) error:NULL closure:^{ + HookToken *token = [obj sh_hookAfterSelector:@selector(sumWithNumber1:number2:) error:NULL closure:^{ NSLog(@"hooked"); }]; [obj sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closure: The hook closure. **WARNING**: The object will retain the closure. So make sure that the closure doesn't retain the object in turn to avoid memory leak because of cycle retain. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc func sh_hookAfter(selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> OCToken { + @objc func sh_hookAfter(selector: Selector, closure: @escaping @convention(block) () -> Void) throws -> HookToken { return try self.sh_hookAfter(selector: selector, closure: closure as Any) } @@ -95,18 +95,18 @@ public extension NSObject { # Example to use the API ``` MyObject *obj = [[MyObject alloc] init]; - OCToken *token = [obj sh_hookBeforeSelector:@selector(sumWithNumber1:number2:) error:NULL closureObjSel:^(NSObject * _Nonnull obj, SEL _Nonnull sel) { + HookToken *token = [obj sh_hookBeforeSelector:@selector(sumWithNumber1:number2:) error:NULL closureObjSel:^(NSObject * _Nonnull obj, SEL _Nonnull sel) { NSLog(@"hooked"); }]; [obj sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closureObjSel: The hook closure. **WARNING**: The object will retain the closure. So make sure that the closure doesn't retain the object in turn to avoid memory leak because of cycle retain. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc func sh_hookBefore(selector: Selector, closureObjSel: @escaping @convention(block) (_ object: NSObject, _ selector: Selector) -> Void) throws -> OCToken { + @objc func sh_hookBefore(selector: Selector, closureObjSel: @escaping @convention(block) (_ object: NSObject, _ selector: Selector) -> Void) throws -> HookToken { return try self.sh_hookBefore(selector: selector, closure: closureObjSel as Any) } @@ -127,18 +127,18 @@ public extension NSObject { # Example to use the API ``` MyObject *obj = [[MyObject alloc] init]; - OCToken *token = [obj sh_hookAfterSelector:@selector(sumWithNumber1:number2:) error:NULL closureObjSel:^(NSObject * _Nonnull obj, SEL _Nonnull sel) { + HookToken *token = [obj sh_hookAfterSelector:@selector(sumWithNumber1:number2:) error:NULL closureObjSel:^(NSObject * _Nonnull obj, SEL _Nonnull sel) { NSLog(@"hooked"); }]; [obj sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closureObjSel: The hook closure. **WARNING**: The object will retain the closure. So make sure that the closure doesn't retain the object in turn to avoid memory leak because of cycle retain. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc func sh_hookAfter(selector: Selector, closureObjSel: @escaping @convention(block) (_ object: NSObject, _ selector: Selector) -> Void) throws -> OCToken { + @objc func sh_hookAfter(selector: Selector, closureObjSel: @escaping @convention(block) (_ object: NSObject, _ selector: Selector) -> Void) throws -> HookToken { return try self.sh_hookAfter(selector: selector, closure: closureObjSel as Any) } @@ -161,11 +161,11 @@ public extension NSObject { # Example to use the API ``` MyObject *obj = [[MyObject alloc] init]; - OCToken *token = [obj sh_hookBeforeSelector:@selector(sumWithNumber1:number2:) closure:^(MyObject * _Nonnull obj, SEL _Nonnull sel, NSInteger number1, NSInteger number2) { + HookToken *token = [obj sh_hookBeforeSelector:@selector(sumWithNumber1:number2:) closure:^(MyObject * _Nonnull obj, SEL _Nonnull sel, NSInteger number1, NSInteger number2) { NSLog(@"hooked"); } error:NULL]; [obj sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closure: The hook closure. **WARNING**: The object will retain the closure. So make sure that the closure doesn't retain the object in turn to avoid memory leak because of cycle retain. The following is a description of the closure @@ -176,9 +176,9 @@ public extension NSObject { - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc func sh_hookBefore(selector: Selector, closure: Any) throws -> OCToken { + @objc func sh_hookBefore(selector: Selector, closure: Any) throws -> HookToken { do { - return OCToken(token: try hookBefore(object: self, selector: selector, closure: closure)) + return try hookBefore(object: self, selector: selector, closure: closure) } catch { guard let swiftHookError = error as? SwiftHookError else { throw error @@ -204,11 +204,11 @@ public extension NSObject { # Example to use the API ``` MyObject *obj = [[MyObject alloc] init]; - OCToken *token = [obj sh_hookAfterSelector:@selector(sumWithNumber1:number2:) closure:^(MyObject * _Nonnull obj, SEL _Nonnull sel, NSInteger number1, NSInteger number2) { + HookToken *token = [obj sh_hookAfterSelector:@selector(sumWithNumber1:number2:) closure:^(MyObject * _Nonnull obj, SEL _Nonnull sel, NSInteger number1, NSInteger number2) { NSLog(@"hooked"); } error:NULL]; [obj sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closure: The hook closure. **WARNING**: The object will retain the closure. So make sure that the closure doesn't retain the object in turn to avoid memory leak because of cycle retain. The following is a description of the closure @@ -219,9 +219,9 @@ public extension NSObject { - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc func sh_hookAfter(selector: Selector, closure: Any) throws -> OCToken { + @objc func sh_hookAfter(selector: Selector, closure: Any) throws -> HookToken { do { - return OCToken(token: try hookAfter(object: self, selector: selector, closure: closure)) + return try hookAfter(object: self, selector: selector, closure: closure) } catch { guard let swiftHookError = error as? SwiftHookError else { throw error @@ -247,13 +247,13 @@ public extension NSObject { # Example to use the API ``` MyObject *obj = [[MyObject alloc] init]; - OCToken *token = [obj sh_hookInsteadWithSelector:@selector(sumWithNumber1:number2:) closure:^NSInteger(NSInteger(^original)(MyObject * _Nonnull obj, SEL _Nonnull sel, NSInteger number1, NSInteger number2), MyObject * _Nonnull obj, SEL _Nonnull sel, NSInteger number1, NSInteger number2) { + HookToken *token = [obj sh_hookInsteadWithSelector:@selector(sumWithNumber1:number2:) closure:^NSInteger(NSInteger(^original)(MyObject * _Nonnull obj, SEL _Nonnull sel, NSInteger number1, NSInteger number2), MyObject * _Nonnull obj, SEL _Nonnull sel, NSInteger number1, NSInteger number2) { NSLog(@"hooked"); // You may call the original method with some different parameters. You can even not call the original method. return original(obj, sel, number1, number2); } error:NULL]; [obj sumWithNumber1:1 number2:2]; - [token cancelHook]; + [token revert]; ``` - parameter selector: The method you want to hook on. - parameter closure: The hook closure. **WARNING**: The object will retain the closure. So make sure that the closure doesn't retain the object in turn to avoid memory leak because of cycle retain. The following is a description of the closure @@ -265,9 +265,9 @@ public extension NSObject { - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc func sh_hookInstead(selector: Selector, closure: Any) throws -> OCToken { + @objc func sh_hookInstead(selector: Selector, closure: Any) throws -> HookToken { do { - return OCToken(token: try hookInstead(object: self, selector: selector, closure: closure)) + return try hookInstead(object: self, selector: selector, closure: closure) } catch { guard let swiftHookError = error as? SwiftHookError else { throw error @@ -283,22 +283,22 @@ public extension NSObject { # Example ``` - OCToken *token = nil; + HookToken *token = nil; @autoreleasepool { NSObject *obj = [[NSObject alloc] init]; token = [obj sh_hookDeallocBeforeAndReturnError:NULL closure:^{ NSLog(@"hooked"); }]; } - [token cancelHook]; + [token revert]; ``` - parameter closure: The hook closure. **WARNING**: The object will retain the closure. So make sure that the closure doesn't retain the object in turn to avoid memory leak because of cycle retain. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc func sh_hookDeallocBefore(closure: @escaping @convention(block) () -> Void) throws -> OCToken { + @objc func sh_hookDeallocBefore(closure: @escaping @convention(block) () -> Void) throws -> HookToken { do { - return OCToken(token: try hookDeallocBefore(object: self, closure: closure)) + return try hookDeallocBefore(object: self, closure: closure) } catch { guard let swiftHookError = error as? SwiftHookError else { throw error @@ -312,14 +312,14 @@ public extension NSObject { # Example ``` - OCToken *token = nil; + HookToken *token = nil; @autoreleasepool { NSObject *obj = [[NSObject alloc] init]; token = [obj sh_hookDeallocBeforeAndReturnError:NULL closureObj:^(NSObject * _Nonnull obj) { NSLog(@"hooked"); }]; } - [token cancelHook]; + [token revert]; ``` - parameter closureObj: The hook closure. @@ -332,9 +332,9 @@ public extension NSObject { - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc func sh_hookDeallocBefore(closureObj: @escaping @convention(block) (_ object: NSObject) -> Void) throws -> OCToken { + @objc func sh_hookDeallocBefore(closureObj: @escaping @convention(block) (_ object: NSObject) -> Void) throws -> HookToken { do { - return OCToken(token: try hookDeallocBefore(object: self, closure: closureObj)) + return try hookDeallocBefore(object: self, closure: closureObj) } catch { guard let swiftHookError = error as? SwiftHookError else { throw error @@ -350,22 +350,22 @@ public extension NSObject { # Example ``` - OCToken *token = nil; + HookToken *token = nil; @autoreleasepool { NSObject *obj = [[NSObject alloc] init]; token = [obj sh_hookDeallocAfterAndReturnError:NULL closure:^{ NSLog(@"hooked"); }]; } - [token cancelHook]; + [token revert]; ``` - parameter closure: The hook closure. **WARNING**: The object will retain the closure. So make sure that the closure doesn't retain the object in turn to avoid memory leak because of cycle retain. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc func sh_hookDeallocAfter(closure: @escaping @convention(block) () -> Void) throws -> OCToken { + @objc func sh_hookDeallocAfter(closure: @escaping @convention(block) () -> Void) throws -> HookToken { do { - return OCToken(token: try hookDeallocAfter(object: self, closure: closure)) + return try hookDeallocAfter(object: self, closure: closure) } catch { guard let swiftHookError = error as? SwiftHookError else { throw error @@ -379,21 +379,21 @@ public extension NSObject { # Example ``` - OCToken *token = nil; + HookToken *token = nil; @autoreleasepool { NSObject *obj = [[NSObject alloc] init]; token = [obj sh_hookDeallocAfterByTailWithClosure:^{ NSLog(@"hooked"); }]; } - [token cancelHook]; + [token revert]; ``` - parameter closure: The hook closure. **WARNING**: The object will retain the closure. So make sure that the closure doesn't retain the object in turn to avoid memory leak because of cycle retain. - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc func sh_hookDeallocAfterByTail(closure: @escaping @convention(block) () -> Void) -> OCToken { - return OCToken(token: hookDeallocAfterByTail(object: self, closure: closure)) + @objc func sh_hookDeallocAfterByTail(closure: @escaping @convention(block) () -> Void) -> HookToken { + return hookDeallocAfterByTail(object: self, closure: closure) } // MARK: replace deinit @@ -403,7 +403,7 @@ public extension NSObject { # Example ``` - OCToken *token = nil; + HookToken *token = nil; @autoreleasepool { NSObject *obj = [[NSObject alloc] init]; token = [obj sh_hookDeallocInsteadAndReturnError:NULL closure:^(void (^ _Nonnull original)(void)) { @@ -412,7 +412,7 @@ public extension NSObject { NSLog(@"after release"); }]; } - [token cancelHook]; + [token revert]; ``` - parameter closure: The hook closure. @@ -423,9 +423,9 @@ public extension NSObject { - returns: The token of this hook behavior. You may cancel this hook through this token. */ @discardableResult - @objc func sh_hookDeallocInstead(closure: @escaping @convention(block) (_ original: () -> Void) -> Void) throws -> OCToken { + @objc func sh_hookDeallocInstead(closure: @escaping @convention(block) (_ original: () -> Void) -> Void) throws -> HookToken { do { - return OCToken(token: try hookDeallocInstead(object: self, closure: closure)) + return try hookDeallocInstead(object: self, closure: closure) } catch { guard let swiftHookError = error as? SwiftHookError else { throw error diff --git a/SwiftHookTests/Advanced/CompatibilityTests.swift b/SwiftHookTests/Advanced/CompatibilityTests.swift index 2e019c56..9543d718 100644 --- a/SwiftHookTests/Advanced/CompatibilityTests.swift +++ b/SwiftHookTests/Advanced/CompatibilityTests.swift @@ -286,7 +286,7 @@ class CompatibilityTests: XCTestCase { let aLog = logs[randomIndex] switch aLog { case let .swiftHook(token: token, start: _, end: _): - token.cancelHook() + token.revert() case .KVO(token: let token, number: _): token.invalidate() } @@ -317,7 +317,7 @@ class CompatibilityTests: XCTestCase { property2Log.forEach { log in if case let .swiftHook(token: token, start: _, end: _) = log { - token.cancelHook() + token.revert() } } diff --git a/SwiftHookTests/Advanced/MethodObjectAndSelectorTest.swift b/SwiftHookTests/Advanced/MethodObjectAndSelectorTest.swift index d5c96d53..21caf1a7 100644 --- a/SwiftHookTests/Advanced/MethodObjectAndSelectorTest.swift +++ b/SwiftHookTests/Advanced/MethodObjectAndSelectorTest.swift @@ -34,7 +34,7 @@ class MethodObjectAndSelectorTest: XCTestCase { XCTAssertTrue(run) // cancel - token.cancelHook() + token.revert() } catch { XCTAssertNil(error) } @@ -79,7 +79,7 @@ class MethodObjectAndSelectorTest: XCTestCase { XCTAssertTrue(run) // cancel - token.cancelHook() + token.revert() } catch { XCTAssertNil(error) } @@ -128,7 +128,7 @@ class MethodObjectAndSelectorTest: XCTestCase { XCTAssertEqual(result, [-1, 0, 1]) // cancel - token.cancelHook() + token.revert() } catch { XCTAssertNil(error) } @@ -210,11 +210,11 @@ class MethodObjectAndSelectorTest: XCTestCase { XCTAssertEqual(result, "2+noArgsNoReturnFunc") // cancel - tokenBefore.cancelHook() - tokenAfter.cancelHook() - tokenInstead1.cancelHook() - tokenInstead2.cancelHook() - tokenInstead3.cancelHook() + tokenBefore.revert() + tokenAfter.revert() + tokenInstead1.revert() + tokenInstead2.revert() + tokenInstead3.revert() } catch { XCTAssertNil(error) } @@ -242,7 +242,7 @@ class MethodObjectAndSelectorTest: XCTestCase { XCTAssertTrue(run) // cancel - token.cancelHook() + token.revert() } catch { XCTAssertNil(error) } @@ -286,7 +286,7 @@ class MethodObjectAndSelectorTest: XCTestCase { XCTAssertTrue(run) // cancel - token.cancelHook() + token.revert() } catch { XCTAssertNil(error) } @@ -334,7 +334,7 @@ class MethodObjectAndSelectorTest: XCTestCase { XCTAssertEqual(result, [-1, 0, 1]) // cancel - token.cancelHook() + token.revert() } catch { XCTAssertNil(error) } @@ -380,7 +380,7 @@ class MethodObjectAndSelectorTest: XCTestCase { XCTAssertTrue(run) // cancel - token.cancelHook() + token.revert() } catch { XCTAssertNil(error) } @@ -423,7 +423,7 @@ class MethodObjectAndSelectorTest: XCTestCase { XCTAssertTrue(run) // cancel - token.cancelHook() + token.revert() } catch { XCTAssertNil(error) } @@ -470,7 +470,7 @@ class MethodObjectAndSelectorTest: XCTestCase { XCTAssertEqual(result, [-1, 0, 1]) // cancel - token.cancelHook() + token.revert() } catch { XCTAssertNil(error) } @@ -548,11 +548,11 @@ class MethodObjectAndSelectorTest: XCTestCase { XCTAssertEqual(result, "3+classNoArgsNoReturnFunc") // cancel - tokenBefore.cancelHook() - tokenAfter.cancelHook() - token1.cancelHook() - token2.cancelHook() - token3.cancelHook() + tokenBefore.revert() + tokenAfter.revert() + token1.revert() + token2.revert() + token3.revert() } catch { XCTAssertNil(error) } diff --git a/SwiftHookTests/Advanced/ParametersCheckingOCTests.m b/SwiftHookTests/Advanced/ParametersCheckingOCTests.m index e57c1833..926d66ef 100644 --- a/SwiftHookTests/Advanced/ParametersCheckingOCTests.m +++ b/SwiftHookTests/Advanced/ParametersCheckingOCTests.m @@ -66,7 +66,7 @@ - (void)test_SwiftHookError_hookKVOUnsupportedInstance { - (void)utilities_test_obj:(NSObject *)obj { NSError *error = nil; - OCToken *token = [obj sh_hookAfterSelector:@selector(isEqual:) error:&error closure:^{ + HookToken *token = [obj sh_hookAfterSelector:@selector(isEqual:) error:&error closure:^{ }]; XCTAssertNil(token); XCTAssertNotNil(error); @@ -100,77 +100,77 @@ - (void)test_Error { ObjectiveCTestObject *object = [[ObjectiveCTestObject alloc] init]; NSError *error = nil; - OCToken *token = [object sh_hookBeforeSelector:NSSelectorFromString(@"retain") error:&error closure:^{ + HookToken *token = [object sh_hookBeforeSelector:NSSelectorFromString(@"retain") error:&error closure:^{ NSLog(@"hooked"); }]; XCTAssertNotNil(error); XCTAssertEqualObjects(error.domain, @"SwiftHook.SwiftHookError"); XCTAssertEqual(error.code, 1); XCTAssertEqualObjects(error.localizedDescription, @"Unsupport to hook current method. Search \"blacklistSelectors\" to see all methods unsupport."); - [token cancelHook]; + [token revert]; } { NSObject *object = [[NSObject alloc] init]; NSError *error = nil; - OCToken *token = [object sh_hookBeforeSelector:@selector(noArgsNoReturnFunc) error:&error closure:^{ + HookToken *token = [object sh_hookBeforeSelector:@selector(noArgsNoReturnFunc) error:&error closure:^{ NSLog(@"hooked"); }]; XCTAssertNotNil(error); XCTAssertEqualObjects(error.domain, @"SwiftHook.SwiftHookError"); XCTAssertEqual(error.code, 3); XCTAssertEqualObjects(error.localizedDescription, @"Can't find the method by the selector from the class."); - [token cancelHook]; + [token revert]; } { ObjectiveCTestObject *object = [[ObjectiveCTestObject alloc] init]; NSError *error = nil; - OCToken *token = [object sh_hookBeforeSelector:@selector(setEmptyStruct:) closure:^(BOOL b){ + HookToken *token = [object sh_hookBeforeSelector:@selector(setEmptyStruct:) closure:^(BOOL b){ NSLog(@"hooked"); } error:&error]; XCTAssertNotNil(error); XCTAssertEqualObjects(error.domain, @"SwiftHook.SwiftHookError"); XCTAssertEqual(error.code, 4); XCTAssertEqualObjects(error.localizedDescription, @"The struct of the method's args or return value is empty, This case can't be compatible with libffi. Please check the parameters or return type of the method."); - [token cancelHook]; + [token revert]; } { ObjectiveCTestObject *object = [[ObjectiveCTestObject alloc] init]; NSError *error = nil; - OCToken *token = [object sh_hookBeforeSelector:@selector(getEmptyStruct) closure:^(BOOL b){ + HookToken *token = [object sh_hookBeforeSelector:@selector(getEmptyStruct) closure:^(BOOL b){ NSLog(@"hooked"); } error:&error]; XCTAssertNotNil(error); XCTAssertEqualObjects(error.domain, @"SwiftHook.SwiftHookError"); XCTAssertEqual(error.code, 4); XCTAssertEqualObjects(error.localizedDescription, @"The struct of the method's args or return value is empty, This case can't be compatible with libffi. Please check the parameters or return type of the method."); - [token cancelHook]; + [token revert]; } { ObjectiveCTestObject *object = [[ObjectiveCTestObject alloc] init]; NSError *error = nil; - OCToken *token = [object sh_hookBeforeSelector:@selector(noArgsNoReturnFunc) closure:[[NSObject alloc] init] error:&error]; + HookToken *token = [object sh_hookBeforeSelector:@selector(noArgsNoReturnFunc) closure:[[NSObject alloc] init] error:&error]; XCTAssertNotNil(error); XCTAssertEqualObjects(error.domain, @"SwiftHook.SwiftHookError"); XCTAssertEqual(error.code, 5); XCTAssertEqualObjects(error.localizedDescription, @"Please check the hook clousre. Is it a standard closure? Does it have keyword @convention(block)?"); - [token cancelHook]; + [token revert]; } { ObjectiveCTestObject *object = [[ObjectiveCTestObject alloc] init]; NSError *error = nil; - OCToken *token = [object sh_hookBeforeSelector:@selector(noArgsNoReturnFunc) closure:^(BOOL b){ + HookToken *token = [object sh_hookBeforeSelector:@selector(noArgsNoReturnFunc) closure:^(BOOL b){ NSLog(@"hooked"); } error:&error]; XCTAssertNotNil(error); XCTAssertEqualObjects(error.domain, @"SwiftHook.SwiftHookError"); XCTAssertEqual(error.code, 6); XCTAssertEqualObjects(error.localizedDescription, @"For `befor` and `after` mode. The parameters type of the hook closure have to be nil or `@:` or as the same as method's. The closure parameters type is `B`. The method parameters type is `@:`. For more about Type Encodings: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html"); - [token cancelHook]; + [token revert]; } { @@ -179,17 +179,17 @@ - (void)test_Error NSLog(@"hooked"); }; NSError *error = nil; - OCToken *token = [object sh_hookBeforeSelector:@selector(noArgsNoReturnFunc) closure:hookClosure error:&error]; + HookToken *token = [object sh_hookBeforeSelector:@selector(noArgsNoReturnFunc) closure:hookClosure error:&error]; XCTAssertNil(error); - OCToken *token2 = [object sh_hookBeforeSelector:@selector(noArgsNoReturnFunc) closure:hookClosure error:&error]; + HookToken *token2 = [object sh_hookBeforeSelector:@selector(noArgsNoReturnFunc) closure:hookClosure error:&error]; XCTAssertNotNil(error); XCTAssertEqualObjects(error.domain, @"SwiftHook.SwiftHookError"); XCTAssertEqual(error.code, 7); XCTAssertEqualObjects(error.localizedDescription, @"This closure has been hooked with current mode already."); - [token cancelHook]; - [token2 cancelHook]; + [token revert]; + [token2 revert]; } { diff --git a/SwiftHookTests/Advanced/SpecialClassTests.m b/SwiftHookTests/Advanced/SpecialClassTests.m index 200fd45f..0867d15b 100644 --- a/SwiftHookTests/Advanced/SpecialClassTests.m +++ b/SwiftHookTests/Advanced/SpecialClassTests.m @@ -51,7 +51,7 @@ - (void)test_NSTaggedPointerString { NSMutableArray *expectation = [[NSMutableArray alloc] init]; NSError *error = nil; - OCToken *token = [obj sh_hookAfterSelector:@selector(length) error:&error closure:^{ + HookToken *token = [obj sh_hookAfterSelector:@selector(length) error:&error closure:^{ [expectation addObject:@1]; }]; XCTAssertNotNil(error); @@ -71,7 +71,7 @@ - (void)test_NSTaggedPointerString { XCTAssertEqual(length2, 4); XCTAssertEqualObjects(expectation, @[]); - [token cancelHook]; + [token revert]; NSUInteger length3 = [obj length]; XCTAssertEqual(length3, 3); XCTAssertEqualObjects(expectation, @[]); @@ -100,7 +100,7 @@ - (void)utilities_test_NSString_obj1:(NSString *)obj1 obj2:(NSString *)obj2 clas XCTAssertEqual(obj1.length, length1); NSError *error = nil; - OCToken *token = [obj1 sh_hookAfterSelector:@selector(length) error:&error closure:^{ + HookToken *token = [obj1 sh_hookAfterSelector:@selector(length) error:&error closure:^{ [expectation addObject:@1]; }]; XCTAssertNotNil(error); @@ -122,7 +122,7 @@ - (void)utilities_test_NSString_obj1:(NSString *)obj1 obj2:(NSString *)obj2 clas XCTAssertEqualObjects(expectation, obj1 == obj2 ? @[@1] : @[]); [expectation removeAllObjects]; - [token cancelHook]; + [token revert]; XCTAssertEqual([obj1 length], length1); XCTAssertEqualObjects(expectation, @[]); @@ -145,7 +145,7 @@ - (void)utilities_test_all_instances_NSString:(NSString *)className obj:(NSStrin IMP originalIMP = class_getMethodImplementation(class, @selector(length)); XCTAssertFalse(originalIMP == NULL); NSError *error = nil; - OCToken *token = [class sh_hookAfterSelector:@selector(length) error:&error closure:^{ + HookToken *token = [class sh_hookAfterSelector:@selector(length) error:&error closure:^{ expectation ++; }]; XCTAssertNil(error); @@ -156,7 +156,7 @@ - (void)utilities_test_all_instances_NSString:(NSString *)className obj:(NSStrin XCTAssertEqual([obj length], length); XCTAssertEqual(expectation, 1); - [token cancelHook]; + [token revert]; expectation = 0; XCTAssertEqual(object_getClass(obj), class); XCTAssertEqual([obj length], length); @@ -188,7 +188,7 @@ - (void)utilities_test_NSArray_obj1:(NSArray *)obj1 obj2:(NSArray *)obj2 classNa XCTAssertEqualObjects([SwiftUtilitiesOCAPI getObjectTypeWithObject:obj2], @"normal"); NSError *error = nil; - OCToken *token = [obj1 sh_hookAfterSelector:@selector(count) error:&error closure:^{ + HookToken *token = [obj1 sh_hookAfterSelector:@selector(count) error:&error closure:^{ [expectation addObject:@1]; }]; XCTAssertNotNil(error); @@ -210,7 +210,7 @@ - (void)utilities_test_NSArray_obj1:(NSArray *)obj1 obj2:(NSArray *)obj2 classNa XCTAssertEqualObjects(expectation, @[]); [expectation removeAllObjects]; - [token cancelHook]; + [token revert]; XCTAssertEqual([obj1 count], count1); XCTAssertEqualObjects(expectation, @[]); @@ -233,7 +233,7 @@ - (void)utilities_test_all_instances_NSArray:(NSString *)className obj:(NSArray IMP originalIMP = class_getMethodImplementation(class, @selector(count)); XCTAssertFalse(originalIMP == NULL); NSError *error = nil; - OCToken *token = [class sh_hookAfterSelector:@selector(count) error:&error closure:^{ + HookToken *token = [class sh_hookAfterSelector:@selector(count) error:&error closure:^{ expectation ++; }]; XCTAssertNil(error); @@ -244,7 +244,7 @@ - (void)utilities_test_all_instances_NSArray:(NSString *)className obj:(NSArray XCTAssertEqual([obj count], count); XCTAssertEqual(expectation, 1); - [token cancelHook]; + [token revert]; expectation = 0; XCTAssertEqual(object_getClass(obj), class); XCTAssertEqual([obj count], count); @@ -277,7 +277,7 @@ - (void)utilities_test_NSDictionary_obj1:(NSDictionary *)obj1 obj2:(NSDictionary XCTAssertEqualObjects([SwiftUtilitiesOCAPI getObjectTypeWithObject:obj2], @"normal"); NSError *error = nil; - OCToken *token = [obj1 sh_hookAfterSelector:@selector(count) error:&error closure:^{ + HookToken *token = [obj1 sh_hookAfterSelector:@selector(count) error:&error closure:^{ [expectation addObject:@1]; }]; XCTAssertEqualObjects(NSStringFromClass([obj1 class]), className); @@ -304,7 +304,7 @@ - (void)utilities_test_NSDictionary_obj1:(NSDictionary *)obj1 obj2:(NSDictionary XCTAssertEqualObjects(expectation, @[]); [expectation removeAllObjects]; - [token cancelHook]; + [token revert]; XCTAssertEqual([obj1 count], count1); XCTAssertEqualObjects(expectation, @[]); @@ -332,7 +332,7 @@ - (void)utilities_test_all_instances_NSDictionary:(NSString *)className obj:(NSD IMP originalIMP = class_getMethodImplementation(class, @selector(count)); XCTAssertFalse(originalIMP == NULL); NSError *error = nil; - OCToken *token = [class sh_hookAfterSelector:@selector(count) error:&error closure:^{ + HookToken *token = [class sh_hookAfterSelector:@selector(count) error:&error closure:^{ expectation ++; }]; XCTAssertNil(error); @@ -343,7 +343,7 @@ - (void)utilities_test_all_instances_NSDictionary:(NSString *)className obj:(NSD XCTAssertEqual([obj count], count); XCTAssertEqual(expectation, 1); - [token cancelHook]; + [token revert]; expectation = 0; XCTAssertEqual(object_getClass(obj), class); XCTAssertEqual([obj count], count); @@ -377,7 +377,7 @@ - (void)utilities_test_NSSet_obj1:(NSSet *)obj1 obj2:(NSSet *)obj2 className:(NS XCTAssertEqualObjects([SwiftUtilitiesOCAPI getObjectTypeWithObject:obj2], @"normal"); NSError *error = nil; - OCToken *token = [obj1 sh_hookAfterSelector:@selector(count) error:&error closure:^{ + HookToken *token = [obj1 sh_hookAfterSelector:@selector(count) error:&error closure:^{ [expectation addObject:@1]; }]; XCTAssertNotNil(error); @@ -399,7 +399,7 @@ - (void)utilities_test_NSSet_obj1:(NSSet *)obj1 obj2:(NSSet *)obj2 className:(NS XCTAssertEqualObjects(expectation, @[]); [expectation removeAllObjects]; - [token cancelHook]; + [token revert]; XCTAssertEqual([obj1 count], count1); XCTAssertEqualObjects(expectation, @[]); @@ -424,7 +424,7 @@ - (void)utilities_test_all_instances_NSSet:(NSString *)className obj:(NSSet *)ob IMP originalIMP = class_getMethodImplementation(class, @selector(count)); XCTAssertFalse(originalIMP == NULL); NSError *error = nil; - OCToken *token = [class sh_hookAfterSelector:@selector(count) error:&error closure:^{ + HookToken *token = [class sh_hookAfterSelector:@selector(count) error:&error closure:^{ expectation ++; }]; XCTAssertNil(error); @@ -435,7 +435,7 @@ - (void)utilities_test_all_instances_NSSet:(NSString *)className obj:(NSSet *)ob XCTAssertEqual([obj count], count); XCTAssertEqual(expectation, 1); - [token cancelHook]; + [token revert]; expectation = 0; XCTAssertEqual(object_getClass(obj), class); XCTAssertEqual([obj count], count); @@ -469,7 +469,7 @@ - (void)utilities_test_NSOrderedSet_obj1:(NSOrderedSet *)obj1 obj2:(NSOrderedSet XCTAssertEqualObjects([SwiftUtilitiesOCAPI getObjectTypeWithObject:obj2], @"normal"); NSError *error = nil; - OCToken *token = [obj1 sh_hookAfterSelector:@selector(count) error:&error closure:^{ + HookToken *token = [obj1 sh_hookAfterSelector:@selector(count) error:&error closure:^{ [expectation addObject:@1]; }]; XCTAssertNotNil(error); @@ -491,7 +491,7 @@ - (void)utilities_test_NSOrderedSet_obj1:(NSOrderedSet *)obj1 obj2:(NSOrderedSet XCTAssertEqualObjects(expectation, @[]); [expectation removeAllObjects]; - [token cancelHook]; + [token revert]; XCTAssertEqual([obj1 count], count1); XCTAssertEqualObjects(expectation, @[]); @@ -516,7 +516,7 @@ - (void)utilities_test_all_instances_NSOrderedSet:(NSString *)className obj:(NSO IMP originalIMP = class_getMethodImplementation(class, @selector(count)); XCTAssertFalse(originalIMP == NULL); NSError *error = nil; - OCToken *token = [class sh_hookAfterSelector:@selector(count) error:&error closure:^{ + HookToken *token = [class sh_hookAfterSelector:@selector(count) error:&error closure:^{ expectation ++; }]; XCTAssertNil(error); @@ -527,7 +527,7 @@ - (void)utilities_test_all_instances_NSOrderedSet:(NSString *)className obj:(NSO XCTAssertEqual([obj count], count); XCTAssertEqual(expectation, 1); - [token cancelHook]; + [token revert]; expectation = 0; XCTAssertEqual(object_getClass(obj), class); XCTAssertEqual([obj count], count); @@ -553,7 +553,7 @@ - (void)test_NSOperation { XCTAssertEqualObjects([SwiftUtilitiesOCAPI getObjectTypeWithObject:obj2], @"normal"); NSError *error = nil; - OCToken *token = [obj1 sh_hookAfterSelector:@selector(setName:) error:&error closure:^{ + HookToken *token = [obj1 sh_hookAfterSelector:@selector(setName:) error:&error closure:^{ [expectation addObject:@1]; }]; XCTAssertNil(error); @@ -574,7 +574,7 @@ - (void)test_NSOperation { XCTAssertEqualObjects(expectation, @[]); [expectation removeAllObjects]; - [token cancelHook]; + [token revert]; obj1.name = @"name3"; XCTAssertEqualObjects(obj1.name, @"name3"); XCTAssertEqualObjects(expectation, @[]); @@ -597,7 +597,7 @@ - (void)test_all_instances_NSOperation{ IMP originalIMP = class_getMethodImplementation(class, @selector(setName:)); XCTAssertFalse(originalIMP == NULL); NSError *error = nil; - OCToken *token = [class sh_hookAfterSelector:@selector(setName:) error:&error closure:^{ + HookToken *token = [class sh_hookAfterSelector:@selector(setName:) error:&error closure:^{ expectation ++; }]; XCTAssertNil(error); @@ -609,7 +609,7 @@ - (void)test_all_instances_NSOperation{ XCTAssertEqualObjects(obj.name, @"name1"); XCTAssertEqual(expectation, 1); - [token cancelHook]; + [token revert]; expectation = 0; XCTAssertEqual(object_getClass(obj), class); obj.name = @"name2"; @@ -637,7 +637,7 @@ - (void)test_NSOperationQueue { XCTAssertEqualObjects([SwiftUtilitiesOCAPI getObjectTypeWithObject:obj2], @"normal"); NSError *error = nil; - OCToken *token = [obj1 sh_hookAfterSelector:@selector(setName:) error:&error closure:^{ + HookToken *token = [obj1 sh_hookAfterSelector:@selector(setName:) error:&error closure:^{ [expectation addObject:@1]; }]; XCTAssertNil(error); @@ -659,7 +659,7 @@ - (void)test_NSOperationQueue { XCTAssertEqualObjects(expectation, @[]); [expectation removeAllObjects]; - [token cancelHook]; + [token revert]; obj1.name = @"name3"; XCTAssertEqualObjects(obj1.name, @"name3"); XCTAssertEqualObjects(expectation, @[]); @@ -682,7 +682,7 @@ - (void)test_all_instances_NSOperationQueue{ IMP originalIMP = class_getMethodImplementation(class, @selector(setName:)); XCTAssertFalse(originalIMP == NULL); NSError *error = nil; - OCToken *token = [class sh_hookAfterSelector:@selector(setName:) error:&error closure:^{ + HookToken *token = [class sh_hookAfterSelector:@selector(setName:) error:&error closure:^{ expectation ++; }]; XCTAssertNil(error); @@ -694,7 +694,7 @@ - (void)test_all_instances_NSOperationQueue{ XCTAssertEqualObjects(obj.name, @"name1"); XCTAssertEqual(expectation, 1); - [token cancelHook]; + [token revert]; expectation = 0; XCTAssertEqual(object_getClass(obj), class); obj.name = @"name2"; @@ -720,7 +720,7 @@ - (void)utilities_test_NSURL_obj:(NSURL *)obj className:(NSString *)className { XCTAssertEqualObjects([SwiftUtilitiesOCAPI getObjectTypeWithObject:obj], @"normal"); NSError *error = nil; - OCToken *token = [obj sh_hookAfterSelector:@selector(host) error:&error closure:^{ + HookToken *token = [obj sh_hookAfterSelector:@selector(host) error:&error closure:^{ [expectation addObject:@1]; }]; XCTAssertNotNil(error); @@ -738,7 +738,7 @@ - (void)utilities_test_NSURL_obj:(NSURL *)obj className:(NSString *)className { XCTAssertEqualObjects(expectation, @[]); [expectation removeAllObjects]; - [token cancelHook]; + [token revert]; XCTAssertEqualObjects([obj host], @"www.google.com"); XCTAssertEqualObjects(expectation, @[]); @@ -756,7 +756,7 @@ - (void)test_all_instances_NSURL{ IMP originalIMP = class_getMethodImplementation(class, @selector(host)); XCTAssertFalse(originalIMP == NULL); NSError *error = nil; - OCToken *token = [class sh_hookAfterSelector:@selector(host) error:&error closure:^{ + HookToken *token = [class sh_hookAfterSelector:@selector(host) error:&error closure:^{ expectation ++; }]; XCTAssertNil(error); @@ -768,7 +768,7 @@ - (void)test_all_instances_NSURL{ XCTAssertEqualObjects(obj.host, @"www.google.com"); XCTAssertEqual(expectation, 1); - [token cancelHook]; + [token revert]; expectation = 0; XCTAssertEqual(object_getClass(obj), class); XCTAssertEqualObjects(obj.host, @"www.google.com"); diff --git a/SwiftHookTests/Advanced/SpecialMethodTests.swift b/SwiftHookTests/Advanced/SpecialMethodTests.swift index c1ba8fd7..e0927bc7 100644 --- a/SwiftHookTests/Advanced/SpecialMethodTests.swift +++ b/SwiftHookTests/Advanced/SpecialMethodTests.swift @@ -175,8 +175,8 @@ class SpecialMethodTests: XCTestCase { i += 1 } } - token1!.cancelHook() - token2!.cancelHook() + token1!.revert() + token2!.revert() XCTAssertEqual(i, 2) } catch { XCTFail() diff --git a/SwiftHookTests/Advanced/StructTests.swift b/SwiftHookTests/Advanced/StructTests.swift index 08a14b7e..32e0f9a5 100644 --- a/SwiftHookTests/Advanced/StructTests.swift +++ b/SwiftHookTests/Advanced/StructTests.swift @@ -32,8 +32,8 @@ class StructTests: XCTestCase { return result } as @convention(block)((AnyObject, Selector, CGPoint, UIEvent?) -> Bool, AnyObject, Selector, CGPoint, UIEvent?) -> Bool) _ = MyObject.init().point(inside: CGPoint.init(x: 11, y: 22), with: nil) - token1.cancelHook() - token2.cancelHook() + token1.revert() + token2.revert() } catch { XCTFail() } @@ -86,8 +86,8 @@ class StructTests: XCTestCase { XCTAssertEqual(result.frame, CGRect.init(x: 44, y: 55, width: 66, height: 77)) XCTAssertEqual(result.s.d, 99) XCTAssertEqual(result.s.s.p, UnsafeMutableRawPointer(pointer)) - token1.cancelHook() - token2.cancelHook() + token1.revert() + token2.revert() } catch { XCTFail() } @@ -136,8 +136,8 @@ class StructTests: XCTestCase { let result = MyObject.init().doublePoint(theStruct: s) XCTAssertEqual(result.frame1, CGRect.init(x: 4, y: 8, width: 12, height: 16)) - token1.cancelHook() - token2.cancelHook() + token1.revert() + token2.revert() } catch { XCTFail() } diff --git a/SwiftHookTests/Advanced/ThreadSafetyTests.swift b/SwiftHookTests/Advanced/ThreadSafetyTests.swift index 52f06830..0716e645 100644 --- a/SwiftHookTests/Advanced/ThreadSafetyTests.swift +++ b/SwiftHookTests/Advanced/ThreadSafetyTests.swift @@ -59,7 +59,7 @@ class ThreadSafetyTests: XCTestCase { } as @convention(block) (AnyObject, Selector, () -> Void) -> Void as AnyObject)) } DispatchQueue.concurrentPerform(iterations: 1000) { index in - tokens[index].cancelHook() + tokens[index].revert() // _ = try internalCancelHook(token: tokens[index]) // This will crash because of non-thread-safe } } @@ -74,7 +74,7 @@ class ThreadSafetyTests: XCTestCase { } as @convention(block) (AnyObject, Selector, () -> Void) -> Void as AnyObject)) } DispatchQueue.concurrentPerform(iterations: 1000) { index in - tokens[index].cancelHook() + tokens[index].revert() // _ = try internalCancelHook(token: tokens[index]) // This will not crash because of non-thread-safe } } @@ -89,7 +89,7 @@ class ThreadSafetyTests: XCTestCase { })) } DispatchQueue.concurrentPerform(iterations: 1000) { index in - tokens[index].cancelHook() + tokens[index].revert() } } diff --git a/SwiftHookTests/Advanced/VariableCaptureTests.swift b/SwiftHookTests/Advanced/VariableCaptureTests.swift index bbc7ad2a..7d2ccd72 100644 --- a/SwiftHookTests/Advanced/VariableCaptureTests.swift +++ b/SwiftHookTests/Advanced/VariableCaptureTests.swift @@ -26,7 +26,7 @@ class VariableCaptureTests: XCTestCase { return result + addNumber } as @convention(block) ((AnyObject, Selector, Int) -> Int, AnyObject, Selector, Int) -> Int) XCTAssertEqual(object.double(number: 11), 25) - token.cancelHook() + token.revert() } } diff --git a/SwiftHookTests/AspectsTests/AspectsSwiftTests.swift b/SwiftHookTests/AspectsTests/AspectsSwiftTests.swift index 17272170..87445a9f 100644 --- a/SwiftHookTests/AspectsTests/AspectsSwiftTests.swift +++ b/SwiftHookTests/AspectsTests/AspectsSwiftTests.swift @@ -120,7 +120,7 @@ class AspectsSwiftTests: XCTestCase { XCTAssertEqual(object.number, 9) expectation = [] - token.cancelHook() + token.revert() XCTAssertTrue(try testGetObjectType(object: object) == .dynamic) object.number = 11 XCTAssertEqual(expectation, [3, 4]) diff --git a/SwiftHookTests/Components/HookDeallocAfterDelegateTests.swift b/SwiftHookTests/Components/HookDeallocAfterDelegateTests.swift index d4fa0a2c..d40d3694 100644 --- a/SwiftHookTests/Components/HookDeallocAfterDelegateTests.swift +++ b/SwiftHookTests/Components/HookDeallocAfterDelegateTests.swift @@ -46,7 +46,7 @@ class HookDeallocAfterDelegateTests: XCTestCase { let token = hookDeallocAfterByDelegate(object: object, closure: { result.append(2) } as @convention(block) () -> Void as AnyObject) - token.cancelHook() + token.revert() } XCTAssertEqual(result, [1]) } diff --git a/SwiftHookTests/OCAPITests/HookAllInstancesOCTests.m b/SwiftHookTests/OCAPITests/HookAllInstancesOCTests.m index 51d489a9..cf155cf6 100644 --- a/SwiftHookTests/OCAPITests/HookAllInstancesOCTests.m +++ b/SwiftHookTests/OCAPITests/HookAllInstancesOCTests.m @@ -10,7 +10,7 @@ @import SwiftHook; BOOL isReleased_HookAllInstancesOCTests = NO; -OCToken *token_HookAllInstancesOCTests = nil; +HookToken *token_HookAllInstancesOCTests = nil; @interface MyObject_HookAllInstancesOCTests : NSObject @property (nonatomic, assign) BOOL run; @@ -54,7 +54,7 @@ - (void)tearDown { [super tearDown]; isReleased_HookAllInstancesOCTests = NO; - [token_HookAllInstancesOCTests cancelHook]; + [token_HookAllInstancesOCTests revert]; token_HookAllInstancesOCTests = nil; } diff --git a/SwiftHookTests/OCAPITests/HookClassMethodsOCTests.m b/SwiftHookTests/OCAPITests/HookClassMethodsOCTests.m index fe18de71..635e144c 100644 --- a/SwiftHookTests/OCAPITests/HookClassMethodsOCTests.m +++ b/SwiftHookTests/OCAPITests/HookClassMethodsOCTests.m @@ -10,7 +10,7 @@ @import SwiftHook; BOOL run_HookClassMethodsOCTests = NO; -OCToken *token_HookClassMethodsOCTests = nil; +HookToken *token_HookClassMethodsOCTests = nil; @interface MyObject_HookClassMethodsOCTests : NSObject @end @@ -47,7 +47,7 @@ - (void)tearDown { [super tearDown]; run_HookClassMethodsOCTests = NO; - [token_HookClassMethodsOCTests cancelHook]; + [token_HookClassMethodsOCTests revert]; token_HookClassMethodsOCTests = nil; } diff --git a/SwiftHookTests/OCAPITests/HookOnceOCTests.m b/SwiftHookTests/OCAPITests/HookOnceOCTests.m index 580e790f..98093301 100644 --- a/SwiftHookTests/OCAPITests/HookOnceOCTests.m +++ b/SwiftHookTests/OCAPITests/HookOnceOCTests.m @@ -33,9 +33,9 @@ - (void)test_specific_object MyObject_HookOnceOCTests *obj = [[MyObject_HookOnceOCTests alloc] init]; __block BOOL run = NO; NSError *error = nil; - __block OCToken *token = [obj sh_hookBeforeSelector:@selector(myMethod) error:&error closure:^{ + __block HookToken *token = [obj sh_hookBeforeSelector:@selector(myMethod) error:&error closure:^{ run = YES; - [token cancelHook]; + [token revert]; }]; XCTAssertNil(error); @@ -58,9 +58,9 @@ - (void)test_objects { __block BOOL run = NO; NSError *error = nil; - __block OCToken *token = [MyObject_HookOnceOCTests sh_hookBeforeSelector:@selector(myMethod) error:&error closure:^{ + __block HookToken *token = [MyObject_HookOnceOCTests sh_hookBeforeSelector:@selector(myMethod) error:&error closure:^{ run = YES; - [token cancelHook]; + [token revert]; }]; XCTAssertNil(error); diff --git a/SwiftHookTests/SwiftAPITests/HookOnceTests.swift b/SwiftHookTests/SwiftAPITests/HookOnceTests.swift index d7d81dde..e00f195d 100644 --- a/SwiftHookTests/SwiftAPITests/HookOnceTests.swift +++ b/SwiftHookTests/SwiftAPITests/HookOnceTests.swift @@ -24,7 +24,7 @@ class HookOnceTests: XCTestCase { var token: Token? token = try hookBefore(object: obj, selector: #selector(MyObject.myMethod)) { run = true - token?.cancelHook() + token?.revert() } XCTAssertFalse(obj.run) XCTAssertFalse(run) @@ -53,7 +53,7 @@ class HookOnceTests: XCTestCase { var token: Token? token = try hookBefore(targetClass: MyObject.self, selector: #selector(MyObject.myMethod)) { run = true - token?.cancelHook() + token?.revert() } let obj1 = MyObject() XCTAssertFalse(obj1.run)