Skip to content

Instantly share code, notes, and snippets.

@rickytan
Last active September 28, 2018 07:25
Show Gist options
  • Save rickytan/fcc9c823985a5e71555feab170059ed7 to your computer and use it in GitHub Desktop.
Save rickytan/fcc9c823985a5e71555feab170059ed7 to your computer and use it in GitHub Desktop.
Safe key path, compile time key-path checking and auto-completion
#define __mz_macro_concat(A, B) __mz_macro_concat_(A, B)
#define __mz_macro_argcount(...) __mz_macro_at(6, __VA_ARGS__, 6, 5, 4, 3, 2, 1)
#define __mz_macro_head(...) __mz_macro_head_(__VA_ARGS__, 0)
#define __mz_macro_at(N, ...) __mz_macro_concat(__mz_macro_at, N)(__VA_ARGS__)
#define __mz_macro_at0(...) __mz_macro_head(__VA_ARGS__)
#define __mz_macro_at1(_0, ...) __mz_macro_head(__VA_ARGS__)
#define __mz_macro_at2(_0, _1, ...) __mz_macro_head(__VA_ARGS__)
#define __mz_macro_at3(_0, _1, _2, ...) __mz_macro_head(__VA_ARGS__)
#define __mz_macro_at4(_0, _1, _2, _3, ...) __mz_macro_head(__VA_ARGS__)
#define __mz_macro_at5(_0, _1, _2, _3, _4, ...) __mz_macro_head(__VA_ARGS__)
#define __mz_macro_at6(_0, _1, _2, _3, _4, _5, ...) __mz_macro_head(__VA_ARGS__)
#define MZKVOKeyPath(Class, ...) __mz_macro_concat(MZKVOKeyPath, __mz_macro_argcount(__VA_ARGS__))(Class, __VA_ARGS__)
#define MZKVOKeyPath0(Class) ((Class *)nil)
#define MZKVOKeyPath1(Class, path0) ((void)(NO && ((void)(((Class *)nil).path0), NO)), @#path0)
#define MZKVOKeyPath2(Class, path0, path1) ((void)(NO && ((void)((((Class *)nil).path0).path1), NO)), @#path0 "." #path1)
#define MZKVOKeyPath3(Class, path0, path1, path2) ((void)(NO && ((void)(((((Class *)nil).path0).path1).path2), NO)), @#path0 "." #path1 "." #path2)
#define MZKVOKeyPath4(Class, path0, path1, path2, path3) ((void)(NO && ((void)((((((Class *)nil).path0).path1).path2).path3), NO)), @#path0 "." #path1 "." #path2 "." #path3)
#define MZKVOKeyPath5(Class, path0, path1, path2, path3, path4) ((void)(NO && ((void)(((((((Class *)nil).path0).path1).path2).path3).path4), NO)), @#path0 "." #path1 "." #path2 "." #path3 "." #path4)
#define MZKVOKeyPath6(Class, path0, path1, path2, path3, path4, path5) ((void)(NO && ((void)((((((((Class *)nil).path0).path1).path2).path3).path4).path5), NO)), @#path0 "." #path1 "." #path2 "." #path3 "." #path4 "." #path5)
#define __mz_macro_concat_(A, B) A ## B
#define __mz_macro_head_(FIRST, ...) FIRST
@iOSleep
Copy link

iOSleep commented Dec 2, 2017

使用[]的形式进行调用会导致使用getter方式的property变量获取不掉,kvo监听的根据的属性名,不是getter的方法名

#define MZKVOKeyPath0(Class) ((Class *)nil)
#define MZKVOKeyPath1(Class, path0) ((void)(NO && ((Class *)nil).path0), @#path0)
#define MZKVOKeyPath2(Class, path0, path1) ((void)(NO && ((Class *)nil).path0.path1), @#path0 "." #path1)
#define MZKVOKeyPath3(Class, path0, path1, path2) ((void)(NO && ((Class *)nil).path0.path1.path2), @#path0 "." #path1 "." #path2)
#define MZKVOKeyPath4(Class, path0, path1, path2, path3) ((void)(NO && ((Class *)nil).path0.path1.path2.path3), @#path0 "." #path1 "." #path2 "." #path3)
#define MZKVOKeyPath5(Class, path0, path1, path2, path3, path4) ((void)(NO && ((Class *)nil).path0.path1.path2.path3.path4), @#path0 "." #path1 "." #path2 "." #path3 "." #path4)
#define MZKVOKeyPath6(Class, path0, path1, path2, path3, path4, path5) ((void)(NO && ((Class *)nil).path0.path1.path2.path3.path4.path5), @#path0 "." #path1 "." #path2 "." #path3 "." #path4 "." #path5)

我进行了调整,您检查下,没有问题就变过来吧。

@rickytan
Copy link
Author

@iOSleep 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment