keypath
一个参数时, 取.后面的子字符串。如果没有.就取字符串本身
二个参数时, 取的第二个参数的字符串。 两个参数,第一个参数的作用在于 自动提示补全OBJ.PATH,实现了代码自动补全的功能
define keypath(...) \
metamacro_if_eq(1, metamacro_argcount(VA_ARGS))(keypath1(VA_ARGS))(keypath2(VA_ARGS))
define keypath1(PATH) \
(((void)(NO && ((void)PATH, NO)), strchr(# PATH, '.') + 1))
define keypath2(OBJ, PATH) \
(((void)(NO && ((void)OBJ.PATH, NO)), # PATH))
keypath(self); //(((void)(__objc_no && ((void)self, __objc_no)), strchr("self", '.') + 1)) ;
keypath(self.view); // (((void)(__objc_no && ((void)self.view, __objc_no)), strchr("self.view", '.') + 1)) ;
keypath(self.view.backgroundColor); //(((void)(__objc_no && ((void)self.view.backgroundColor, __objc_no)), strchr("self.view.backgroundColor", '.') + 1)) ;
keypath(self, view.backgroundColor); // (((void)(__objc_no && ((void)self.view.backgroundColor, __objc_no)), "view.backgroundColor"));
keypath(self.view,backgroundColor); // (((void)(__objc_no && ((void)self.view.backgroundColor, __objc_no)), "backgroundColor"));
keypath(self.view.backgroundColor,CGColor); //(((void)(__objc_no && ((void)self.view.backgroundColor.CGColor, __objc_no)), "CGColor"));
1、 RACObserve
RACObserve(self, kvoValue);
({ __attribute__((objc_ownership(weak))) id target_ = (self);
[target_ rac_valuesForKeyPath:@(((void)(__objc_no && ((void)self.kvoValue, __objc_no)), "kvoValue")) observer:self]; });
- (RACSignal *)rac_valuesForKeyPath:(NSString *)keyPath observer:(__weak NSObject *)observer {
return [[[self
rac_valuesAndChangesForKeyPath:keyPath options:NSKeyValueObservingOptionInitial observer:observer]
map:^(RACTuple *value) {
// -map: because it doesn't require the block trampoline that -reduceEach: uses
return value[0];
}]
setNameWithFormat:@"RACObserve(%@, %@)", RACDescription(self), keyPath];
}
2、 RACChannelTo
RACChannelTo(self.view, backgroundColor) = RACChannelTo(self,sscolor);
[[RACKVOChannel alloc] initWithTarget:(self.view) keyPath:
@(((void)(__objc_no && ((void)self.view.backgroundColor, __objc_no)), "backgroundColor"))
nilValue:(((void *)0))]
[@(((void)(__objc_no && ((void)RACKVOChannel.new.followingTerminal, __objc_no)), "followingTerminal"))]
= [[RACKVOChannel alloc] initWithTarget:(self) keyPath:
@(((void)(__objc_no && ((void)self.sscolor, __objc_no)), "sscolor"))
nilValue:(((void *)0))]
[@(((void)(__objc_no && ((void)RACKVOChannel.new.followingTerminal, __objc_no)), "followingTerminal"))] ;
// 下标操作
@implementation RACKVOChannel (RACChannelTo)
-
(RACChannelTerminal *)objectForKeyedSubscript:(NSString *)key {
NSCParameterAssert(key != nil);RACChannelTerminal *terminal = [self valueForKey:key];
NSCAssert([terminal isKindOfClass:RACChannelTerminal.class], @"Key "%@" does not identify a channel terminal", key);return terminal;
} -
(void)setObject:(RACChannelTerminal *)otherTerminal forKeyedSubscript:(NSString *)key {
NSCParameterAssert(otherTerminal != nil);RACChannelTerminal *selfTerminal = [self objectForKeyedSubscript:key];
[otherTerminal subscribe:selfTerminal];
[[selfTerminal skip:1] subscribe:otherTerminal];
}
3、 RAC
[[RACSubscriptingAssignmentTrampoline alloc] initWithTarget:(TARGET) nilValue:(NILVALUE)][@keypath(TARGET, KEYPATH)]
[[RACSubscriptingAssignmentTrampoline alloc] initWithTarget:(self.view) nilValue:([UIColor redColor])]
[@(((void)(__objc_no && ((void)self.view.backgroundColor, __objc_no)),
"backgroundColor"))]=a;
// 下标操作
- (void)setObject:(RACSignal *)signal forKeyedSubscript:(NSString *)keyPath {
[signal setKeyPath:keyPath onObject:self.target nilValue:self.nilValue];
}
网友评论