安全的 keypath

有更简单的方法,以下不要再看了吧。。。

#define MZKeyPath(OBJ, PATH) \
(((void)(NO && ((void)(((typeof(OBJ))nil).PATH), NO)), @# PATH))

// 支持类或实例两种写法:
- (void)viewDidLoad
{
    [super viewDidLoad];
    MZKeyPath(NSString *, lowercaseString.uppercaseString.length);
    MZKeyPath(self, title.lowercaseString.uppercaseString.UTF8String);
}

KVOKVCObjective-C 语言非常强大的两个特性,从一开始的似懂非懂到慢慢了解它的底层实现,才感受到这门动态语言的魅力所在。 KVC 允许通过一个点分隔的字符串来设置一个对象的属性值,而 KVO 可以通过点分隔的字符串来监听对象属性值的改变。

@interface Foo : NSObject
@property (nonatomic) NSString *name;
@property (nonatomic) NSInteger age;
@end

@interface Bar : NSObject
@property (nonatomic) Foo *foo;
@end

Bar *bar = [Bar new];  
[bar addObserver:self
      forKeyPath:@"foo.name"
         options:NSKeyValueObservingOptionNew
         context:NULL];
[bar setValue:@20 forKeyPath:@"foo.age"];    // 当然这个是无效的,因为 foo 为 nil

既然是字符串,人就可能犯错,因为它无法自动补全。比如常见的拼写错误,或者一个不存在的 keypath。如何能让 Xcode 在编译时就检查出这些错误呢?

libextobjc 的启发,本人作了一个宏来处理此事,编译时检查错误,且能自动补全。

使用方法

MZKVOKeyPath 宏中,第一个参数传一个 Class 类型,后面跟它的实例的属性,就像使用 . 点操作一样,可以一级一级往下。

注意:最多支持到六层 keypath,需要更多您可以自己修改。