前段时间转载了一个Objective-C Associative References(关联引用) 一篇文章,今天在看KVC方面的文章,所以就想到结合一起再讲明白一点,更加结合实际一点
有时候我们需要在系统的回调方法里做一些事情,但是这个会掉方法里并拿不到我们需要的对象,可能,我们意识里,第一个想到的就是设置一个全局变量,但是这样就到处都是,代码难以维护。例如下面一个例子:
CAKeyframeAnimation *animation=[CAKeyframeAnimation animationWithKeyPath:@"position"]; keyPosi.path=path; keyPosi.delegate=self; [label.layer addAnimation:animation forKey:@"position"];
我想在这个动画结束的时候移除
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{ }
可是拿不到UIView对象,我就想用KVC 的方式实现存进去
[animation setValue:view forKey:@"xx"];
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{ if (flag) { UIView *vie=[anim valueForKey:@"xx"]; [vie removeFromSuperview]; } }
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSObject 0xf65f090> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key xx.'运行出现以上错误。
查阅官方文档
setValue:forUndefinedKey: Invoked by setValue:forKey: when it finds no property for a given key. - (void)setValue:(id)value forUndefinedKey:(NSString *)key Discussion Subclasses can override this method to handle the request in some other way. The default implementation raises an NSUndefinedKeyException.
所以只能使用动态关联机制associative和category,加以实现KVC。
#import <objc/runtime.h> @interface NSObject (KVC) - (id)valueForUndefinedKey:(NSString *)key; - (void)setValue:(id)value forUndefinedKey:(NSString *)key; @end @implementation NSObject(KVC) - (id)valueForUndefinedKey:(NSString *)key{ return objc_getAssociatedObject(self, key); } - (void)setValue:(id)value forUndefinedKey:(NSString *)key{ if ([value isKindOfClass:[NSString class]]) { objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_COPY_NONATOMIC); }else{ objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } } @end