Commit 658b09c3 authored by 李杰's avatar 李杰
Browse files

release 0.1.1

Showing with 100 additions and 35 deletions
+100 -35
......@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
#
s.name = "JJException"
s.version = "0.1.0"
s.version = "0.1.1"
s.summary = "Handle the objective-c crash exception."
# This description is used to generate tags and improve search results.
......
No preview for this file type
......@@ -9,14 +9,14 @@
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "JJException/Source/MRC/NSObject+KVOCrash.m"
timestampString = "561277038.212747"
filePath = "JJException/Source/MRC/NSObject+UnrecognizedSelectorHook.m"
timestampString = "561397405.780197"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "138"
endingLineNumber = "138"
landmarkName = "-clearKVOData"
landmarkType = "7">
startingLineNumber = "10"
endingLineNumber = "10"
landmarkName = "unknown"
landmarkType = "0">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
......@@ -25,35 +25,30 @@
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "JJException/Source/MRC/NSObject+KVOCrash.m"
timestampString = "561277038.213109"
filePath = "JJException/Source/ARC/NSNotificationCenter+ClearNotification.m"
timestampString = "561635354.75411"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "187"
endingLineNumber = "187"
landmarkName = "-hookAddObserver:forKeyPath:options:context:"
startingLineNumber = "29"
endingLineNumber = "29"
landmarkName = "-processAddObserver:selector:name:object:swizzleInfo:"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.SymbolicBreakpoint">
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "[NSObject addObserver:forKeyPath:options:context:]"
moduleName = "">
<Locations>
<Location
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "-[NSObject(NSKeyValueObserverRegistration) addObserver:forKeyPath:options:context:]"
moduleName = "Foundation"
usesParentBreakpointCondition = "Yes"
offsetFromSymbolStart = "0">
</Location>
</Locations>
filePath = "JJException/Source/Swizzle/NSObject+SwizzleHook.m"
timestampString = "561635354.754173"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "109"
endingLineNumber = "109"
landmarkName = "__JJ_SWIZZLE_BLOCK"
landmarkType = "9">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
......
......@@ -14,17 +14,23 @@
@implementation NSNotificationCenter (ClearNotification)
+ (void)jj_swizzleNSNotificationCenter{
swizzleInstanceMethod([NSNotificationCenter class], @selector(addObserver:selector:name:object:), @selector(hookAddObserver:selector:name:object:));
[self jj_swizzleInstanceMethod:@selector(addObserver:selector:name:object:) withSwizzledBlock:^id(JJSwizzleObject *swizzleInfo) {
return ^(__unsafe_unretained id self,id observer,SEL aSelector,NSString* aName,id anObject){
[self processAddObserver:observer selector:aSelector name:aName object:anObject swizzleInfo:swizzleInfo];
};
}];
}
- (void)hookAddObserver:(id)observer selector:(SEL)aSelector name:(NSNotificationName)aName object:(id)anObject{
- (void)processAddObserver:(id)observer selector:(SEL)aSelector name:(NSNotificationName)aName object:(id)anObject swizzleInfo:(JJSwizzleObject*)swizzleInfo{
if (observer) {
__unsafe_unretained typeof(observer) unsafeObject = observer;
[observer jj_deallocBlock:^{
[[NSNotificationCenter defaultCenter] removeObserver:unsafeObject];
}];
[self hookAddObserver:observer selector:aSelector name:aName object:anObject];
void(*originIMP)(__unsafe_unretained id,SEL,id,SEL,NSString*,id);
originIMP = (__typeof(originIMP))[swizzleInfo getOriginalImplementation];
originIMP(self,swizzleInfo.selector,observer,aSelector,aName,anObject);
}
}
......
......@@ -8,6 +8,18 @@
#import <Foundation/Foundation.h>
typedef void (*JJSwizzleOriginalIMP)(void /* id, SEL, ... */ );
@interface JJSwizzleObject : NSObject
- (JJSwizzleOriginalIMP)getOriginalImplementation;
@property (nonatomic,readonly,assign) SEL selector;
@end
typedef id (^JJSwizzledIMPBlock)(JJSwizzleObject* swizzleInfo);
void swizzleClassMethod(Class cls, SEL originSelector, SEL swizzleSelector);
void swizzleInstanceMethod(Class cls, SEL originSelector, SEL swizzleSelector);
......@@ -18,4 +30,6 @@ void swizzleInstanceMethod(Class cls, SEL originSelector, SEL swizzleSelector);
- (void)jj_swizzleInstanceMethod:(SEL)originSelector withSwizzleMethod:(SEL)swizzleSelector;
- (void)jj_swizzleInstanceMethod:(SEL)originSelector withSwizzledBlock:(JJSwizzledIMPBlock)swizzledBlock;
@end
......@@ -8,9 +8,25 @@
#import "NSObject+SwizzleHook.h"
#import <objc/runtime.h>
#import <libkern/OSAtomic.h>
void swizzleClassMethod(Class cls, SEL originSelector, SEL swizzleSelector)
{
typedef IMP (^JJSWizzleImpProvider)(void);
@interface JJSwizzleObject()
@property (nonatomic,readwrite,copy) JJSWizzleImpProvider impProviderBlock;
@property (nonatomic,readwrite,assign) SEL selector;
@end
@implementation JJSwizzleObject
- (JJSwizzleOriginalIMP)getOriginalImplementation{
NSAssert(_impProviderBlock,nil);
return (JJSwizzleOriginalIMP)_impProviderBlock();
}
@end
void swizzleClassMethod(Class cls, SEL originSelector, SEL swizzleSelector){
if (!cls) {
return;
}
......@@ -40,8 +56,7 @@ void swizzleClassMethod(Class cls, SEL originSelector, SEL swizzleSelector)
}
}
void swizzleInstanceMethod(Class cls, SEL originSelector, SEL swizzleSelector)
{
void swizzleInstanceMethod(Class cls, SEL originSelector, SEL swizzleSelector){
if (!cls) {
return;
}
......@@ -75,6 +90,35 @@ void swizzleInstanceMethod(Class cls, SEL originSelector, SEL swizzleSelector)
@implementation NSObject (SwizzleHook)
void __JJ_SWIZZLE_BLOCK(Class classToSwizzle,SEL selector,JJSwizzledIMPBlock impBlock){
Method method = class_getInstanceMethod(classToSwizzle, selector);
__block IMP originalIMP = NULL;
JJSWizzleImpProvider originalImpProvider = ^IMP{
IMP imp = originalIMP;
if (NULL == imp){
Class superclass = class_getSuperclass(classToSwizzle);
imp = method_getImplementation(class_getInstanceMethod(superclass,selector));
}
return imp;
};
JJSwizzleObject* swizzleInfo = [JJSwizzleObject new];
swizzleInfo.selector = selector;
swizzleInfo.impProviderBlock = originalImpProvider;
id newIMPBlock = impBlock(swizzleInfo);
const char* methodType = method_getTypeEncoding(method);
IMP newIMP = imp_implementationWithBlock(newIMPBlock);
originalIMP = class_replaceMethod(classToSwizzle, selector, newIMP, methodType);
}
+ (void)jj_swizzleClassMethod:(SEL)originSelector withSwizzleMethod:(SEL)swizzleSelector{
swizzleClassMethod(self.class, originSelector, swizzleSelector);
}
......@@ -83,4 +127,8 @@ void swizzleInstanceMethod(Class cls, SEL originSelector, SEL swizzleSelector)
swizzleInstanceMethod(self.class, originSelector, swizzleSelector);
}
- (void)jj_swizzleInstanceMethod:(SEL)originSelector withSwizzledBlock:(JJSwizzledIMPBlock)swizzledBlock{
__JJ_SWIZZLE_BLOCK(self.class, originSelector, swizzledBlock);
}
@end
......@@ -314,7 +314,9 @@ Method swizzling整个过程需要线程安全,如果你只是在`+(void)load`
A类有一个方法a1,Swizzled的方法是a2,在执行原始方法时,取_cmd参数时是`a2`,如果a1方法体里有依赖_cmd时,就会出现问题。
所以`RSSwizzle``Aspects`都是用block来规避这个问题的,__所以在JJException的0.1.1版本中将用RSSwizzle的方式来实现Hook__
`RSSwizzle`是用block和IMP来规避这个问题的,`RSSwizzle`是真正避开这个问题的,因为对外接口就是IMP,所以他用宏对外,使用的比较生涩.
`Aspects`其实没有安全避开这个问题,不过它主要保证`forwardInvocation:`没有依赖_cmd,就没有这个问题.
* Swizzle执行顺序
......
......@@ -65,7 +65,7 @@ typedef NS_OPTIONS(NSInteger,JJExceptionGuardCategory){
};
```
* 设置异常类型并开启
* 设置异常类型并开启,__建议放在`didFinishLaunchingWithOptions`第一行,以免在多线程出现异常的情况__
```objc
[JJException configExceptionCategory:JJExceptionGuardAll];
[JJException startGuardException];
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment