Write a category to NSObject:
#import <Foundation/Foundation.h>
@interface NSObject (Fmobserverhelper)
-(void) Fm_addobserver: (NSOBJECT *) Observer Forkeypath: (NSString *) KeyPath;
@end
The Dealloc method is called before the object is freed, and the instance variables it holds are also freed.
When listening for registration, a temporary object is associated for self and observer, and when both are releasing the instance variable, the opportunity is taken to remove the observer in the Dealloc method of the temporary object.
The self is freed before it is released, and the self is not completely freed, but the target is nil in the temporary object.
Weak: The holder does not retain the target, and when the target is destroyed, the holder's instance variable is empty
Unsafe_unretained: The holder does not retain the target, and when the target is released, the holder's instance variable still points to the previous memory space (wild pointer)
If the Observer is released early, and the associated attribute is added, both cannot hold the temporary object at the same time, otherwise the temporary object will not be released in time, since one does not, then it is related to each other.
Two associated properties were released at the same time, the removal operation was observed two times. To avoid this problem, you need to determine whether the instance variable factor referenced by weak is empty.
#import "Nsobject+fmobserverhelper.h"
#import <objc/runtime.h>
@interface Fmobserverhelper:nsobject
@property (nonatomic, unsafe_unretained) ID target;
@property (nonatomic, unsafe_unretained) ID observer;
@property (nonatomic, Strong) NSString * KEYPATH;
@property (nonatomic, weak) fmobserverhelper * factor;
@end
@implementation Fmobserverhelper
-(void) Dealloc {
if (_factor) {
[_target Removeobserver:_observer Forkeypath:_keypath];
}
}
@end
@implementation NSObject (Fmobserverhelper)
-(void) Fm_addobserver: (NSOBJECT *) Observer Forkeypath: (NSString *) KeyPath {
[Self addobserver:observer forkeypath:keypath options:nskeyvalueobservingoptionnew Context:nil];
Fmobserverhelper * helper = [Fmobserverhelper new];
Fmobserverhelper * Sub = [Fmobserverhelper new];
Sub.target = Helper.target = self;
Sub.observer = HELPER.OBSERVER = Observer;
Sub.keypath = Helper.keypath = KeyPath;
Helper.factor = Sub;
Sub.factor = helper;
const char * helpekey = [NSString stringwithformat:@ "%ZD", [observer hash]]. utf8string;
Objc_setassociatedobject (self, helpekey, helper, objc_association_retain_nonatomic);
OBJC_SETASSOCIATEDOBJECT (Observer, Helpekey, Sub, objc_association_retain_nonatomic);
}
@end
IOS Auto-Remove KVO Viewer