Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
//
// NSObject+KVOWeakPropertyDebug.h
// KVOWeakPropertyDebug
//
// Created by Vladimir Grichina on 12.01.13.
// Copyright (c) 2013 Vladimir Grichina. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSObject (KVOWeakPropertyDebug)
@end
//
// NSObject+KVOWeakPropertyDebug.m
// KVOWeakPropertyDebug
//
// Created by Vladimir Grichina on 12.01.13.
// Copyright (c) 2013 Vladimir Grichina. All rights reserved.
//
#import "NSObject+KVOWeakPropertyDebug.h"
#import <objc/runtime.h>
void MethodSwizzle(Class c, SEL origSEL, SEL overrideSEL)
{
Method origMethod = class_getInstanceMethod(c, origSEL);
Method overrideMethod = class_getInstanceMethod(c, overrideSEL);
if (class_addMethod(c, origSEL, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) {
class_replaceMethod(c, overrideSEL, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
} else {
method_exchangeImplementations(origMethod, overrideMethod);
}
}
@implementation NSObject (KVOWeakPropertyDebug)
+ (void)load
{
MethodSwizzle(self, @selector(addObserver:forKeyPath:options:context:), @selector(_addObserver:forKeyPath:options:context:));
}
- (BOOL)_isWeak:(NSString *)keyPath
{
// TODO: Support complex keyPath variants
objc_property_t property = class_getProperty(self.class, keyPath.UTF8String);
if (property) {
return property_getAttributes(property)[3] == 'W';
}
return NO;
}
- (void)_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context
{
if ([self _isWeak:keyPath]) {
NSLog(@"WARNING: observing '%@' property, which is weak and so isn't fully KVO-compliant", keyPath);
}
[self _addObserver:observer forKeyPath:keyPath options:options context:context];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment