Skip to content

Commit f884229

Browse files
committed
swizzl dealloc for KVO crash protector
1 parent fd3cf4f commit f884229

File tree

6 files changed

+25
-11
lines changed

6 files changed

+25
-11
lines changed

.DS_Store

0 Bytes
Binary file not shown.

HardShell/Source/NSObject+HardShell.m

+13-9
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ + (void)load {
5050
});
5151
}
5252

53+
// TODO: swizzle observeValueForKeyPath
5354
- (void)hsAddObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context {
5455

5556
if(!self.kvoProtector) {
@@ -59,7 +60,7 @@ - (void)hsAddObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath option
5960

6061
NSDictionary *kvoInfo;
6162
if(context) {
62-
kvoInfo = @{@"Observer": observer, @"KeyPath": keyPath, @"Options": [NSNumber numberWithInteger:options], @"Context": (__bridge NSObject *)(context)};
63+
kvoInfo = @{@"Observer": observer, @"Observed": self, @"KeyPath": keyPath, @"Options": [NSNumber numberWithInteger:options], @"Context": (__bridge NSObject *)(context)};
6364
} else {
6465
kvoInfo = @{@"Observer": observer, @"KeyPath": keyPath, @"Options": [NSNumber numberWithInteger:options]};
6566
}
@@ -93,7 +94,7 @@ - (void)hsAddObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath option
9394
- (void)hsRemoveObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath {
9495

9596
if(!self.kvoProtector) {
96-
NSLog(@"Error: no observer obserse you.");
97+
NSLog(@"Error: no observer observes you.");
9798
return;
9899
} else {
99100
HSKVOProtector *kvoProtector = self.kvoProtector;
@@ -114,18 +115,20 @@ - (void)hsRemoveObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath {
114115
if (kvoInfoArray.count == 0) {
115116
NSMutableDictionary *mutableObserverDict = [observerDict mutableCopy];
116117
[mutableObserverDict removeObjectForKey:keyPath];
117-
[self removeObserver:kvoProtector forKeyPath:keyPath];
118+
[self hsRemoveObserver:kvoProtector forKeyPath:keyPath];
118119
}
119120

120121
}
121122
}
122123

123124
}
124125

125-
- (void)hsObserveValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
126-
127-
NSLog(@"hsObserveValueForKeyPath");
128-
126+
- (void)hsDealloc {
127+
if(self.kvoProtector) {
128+
NSMutableDictionary *mutableObserverDict = [self.kvoProtector.observerDict mutableCopy];
129+
[mutableObserverDict removeAllObjects];
130+
self.kvoProtector = nil;
131+
}
129132
}
130133

131134
+ (void)swizzleAddObserver {
@@ -144,9 +147,10 @@ + (void)swizzleRemoveObserver {
144147
}
145148
}
146149

147-
+ (void)swizzleObserveValueForKeyPath {
150+
+ (void)swizzleDealloc {
148151
NSError *error;
149-
BOOL success = [[self class] jr_swizzleMethod:@selector(removeObserver:forKeyPath:) withMethod:@selector(hsObserveValueForKeyPath:ofObject:change:context:) error:&error];
152+
const SEL deallocSel = NSSelectorFromString(@"dealloc");
153+
BOOL success = [[self class] jr_swizzleMethod:deallocSel withMethod:@selector(hsDealloc) error:&error];
150154
if (!success || error) {
151155
NSLog(@"Can't swizzle methods - %@", [error description]);
152156
}

HardShell/ViewController.m

-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ - (void)viewDidLoad {
3535
[label removeObserver:self forKeyPath:@"textColor"];
3636

3737
//label.text = @"new text";
38-
3938
}
4039

4140

README.md

+12-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ HardShell is a protector to keep app from specific crashes. Now it only protects
44

55
The idea is from [Baymax's introduction](https://neyoufan.github.io/2017/01/13/ios/BayMax_HTSafetyGuard/) which is from Wangyi (Hangzhou). They promise Baymax SDK will be released but don't mention the schedule and if it will be opensourced. So I build HardShell.
66

7-
It is still at early stages and not product ready to launch. Please help me to do more testing. Pull requests are always highly welcomed.
7+
It is still at early stages and not product ready to launch. Please help me to do more testing. Pull requests are always highly welcomed.
88

99
### unrecognized selector crash
1010

@@ -27,6 +27,17 @@ The crash disappeared and the root cause is shown.
2727

2828
<img src="Screenshots/After.png" align="center" height="28" width="400">
2929

30+
### KVO crash
31+
32+
1. add same observer repeatedly for same key path
33+
2. remove same observation repeatedly
34+
3. remove nonexistent observation
35+
For example:
36+
37+
<img src="Screenshots/KVOCode.png" align="center" height="135" width="589">
38+
39+
<img src="Screenshots/KVOLog.png" align="center" height="777" width="404">
40+
3041
Other features will come soon.
3142

3243
### License

Screenshots/KVOCode.png

153 KB
Loading

Screenshots/KVOLog.png

84.5 KB
Loading

0 commit comments

Comments
 (0)