向属性添加自定义属性并不常见,但我认为是可取的。此功能可用于自定义遍历类的属性。我在处理 SQL 时需要这个功能:如果我们有类似的属性:EXCLUDE_FROM_SELECT
, INCLUDE_BY_INSERT
, EXCLUDE_FROM_UPDATE
... 那么它会非常好。
实际上,我不确定是否有办法为 @property 指令启用它。但是,我们也许可以做类似的事情:
如果你看一下 objc/runtime.h 你会发现一个函数:class_replaceProperty
,它没有记录在官方网站上。记录了一个类似的函数class_addProperty
,可以帮助您理解前一个的论点。实际上,我认为@property 利用这个函数来进行属性设置(但我无法证明它确实如此)。
您可能还需要以下功能:
void class_copyPropertyList(...);
void property_copyAttributeList(...);
void class_getProperty(...);
通过使用这些函数,您可以执行@property 实际执行的操作。
我对前面的 SQL 问题所做的是定义 3 个函数来注册自定义属性:
void prepareClass(...);
void registerAttributes(...);
void endRegister(...);
然后我们可以在+initialize
您的 tagart 类的函数中进行注册。
但是,使用代码(与简单的@interface + @property 声明相比)可能不是您的最佳解决方案,因为我们可能希望直接从声明中查看属性设置。__attribute__((constructor))
实际上我们可以通过使用and 宏来做得更好:
@interface @end 实际上允许您这样做:
@interface MyVO : NSObject
__attribute__((constructor))
void prepareForMyVO(){ prepareClass(MyVO);}
@property (strong) id p1;
__attribute__((constructor))
static void registerAttrForP1(){ registerAttributes("p1", EXCLUDE_FROM_SELECT);}
@property (strong) id p2;
__attribute__((constructor))
static void registerAttrForP2(){ registerAttributes("p2", INCLUDE_BY_INSERT);}
@end
__attribute__((constructor))
static void endRegisterForMyOV(){ endRegister();};
因此,您可以定义宏来处理此硬代码:
#define $p(clazz, zuper) class : zuper \
__attribute__((constructor)) static void prepareFor ## clazz(){ prepareClass(#MyVO);}
#define $r(p, attr) p; \
__attribute__((constructor)) static void registerAttrFor ## p(){ registerAttributes(#p, attr);}
#define $e(clazz) __attribute__((constructor)) static void endRegister ## clazz(){ endRegister();};
@interface $p(MyVO, NSObject)
@property (strong) id $r(p1, EXCLUDE_FROM_SELECT);
@property (strong) id $r(p1, INCLUDE_BY_INSERT);
@end $e(MyVO)
PS:上面的编码不是确切的编码,它只是一个例子。而且我不确定最后一个宏解决方案是否有效,希望这会有所帮助。