我想要拥有类级别的属性,我从 https://stackoverflow.com/a/15811719/157384 找到了解决方案
@interface Model
+ (int) value;
+ (void) setValue:(int)val;
@end
@implementation Model
static int value;
+ (int) value
{ @synchronized(self) { return value; } }
+ (void) setValue:(int)val
{ @synchronized(self) { value = val; } }
@end
现在您可以通过属性访问器进行调用,如下所示:
Model.value = 1
Model.value // => 1
太棒了!
现在,我想以某种形式的宏或元编程使这段代码可重用,它需要属性名称和类型。怎么写呢?
在上面的示例中,value
和 (int)
(以及 Model
)应该是动态的。
更新
感谢@Rich,我现在有了这个:
// Common.h
#define CLASS_PROPERTY_INTERFACE(TYPE, METHOD, CMETHOD) \
+ (TYPE) METHOD; \
+ (void) set##CMETHOD:(TYPE)val; \
#define CLASS_PROPERTY_IMPLEMENTATION(TYPE, METHOD, CMETHOD) \
static TYPE _##METHOD; \
+ (TYPE) METHOD \
{ @synchronized(self) { return _##METHOD; } } \
+ (void) set##CMETHOD:(TYPE)val \
{ @synchronized(self) { _##METHOD = val; } } \
// User.h
@interface User : NSObject
CLASS_PROPERTY_INTERFACE(User *, me, Me)
@end
// User.m
@implementation User
CLASS_PROPERTY_IMPLEMENTATION(User *, me, Me)
@end
User.me = currentUser;
User.me // => currentUser
剩下要做的一件事是,如果可能的话,自动将传递给宏的方法名称大写。
但它已经比现有的样板简洁得多了!
最佳答案
宏观方式...
注意: 这有点可怕,我真的不建议使用它,但正在尝试在宏中定义它们......
需要注意的是(除了它不太“好”之外),setter 方法的格式为 set_XXX:
格式。
#define CLASS_INTERFACE(CLS_NAME, METHOD, TYPE) @interface CLS_NAME : NSObject \
+ (TYPE) METHOD; \
+ (void) set_##METHOD:(TYPE)val; \
@end \
#define CLASS_IMPLEMENTATION(CLS_NAME, METHOD, TYPE) @implementation CLS_NAME \
static TYPE METHOD; \
+ (TYPE) METHOD \
{ @synchronized(self) { return METHOD; } } \
+ (void) set_##METHOD:(TYPE)val \
{ @synchronized(self) { METHOD = val; } } \
@end \
将以下内容放入头文件中:
CLASS_INTERFACE(Test, value, int)
在 .m
文件中:
CLASS_IMPLEMENTATION(Test, value, int)
然后使用Test
类:
[Test set_value:4];
int i = [Test value];
同样,这非常可怕,但会起作用......!
编辑:
使用单例
正如评论中提到的,我认为使用单例更好,这使我编写了更可怕的代码:(
现在我们已经(准备好病袋):
#define SINGLETON_INTERFACE_START(CLS_NAME) @interface CLS_NAME : NSObject \
+(instancetype) sharedInstance; \
#define SINGLETON_INTERFACE_END(CLS_NAME) \
@end \
static inline CLS_NAME * CLS_NAME##Global () { return [CLS_NAME sharedInstance]; }
#define SINGLETON_IMPLEMENTATION(CLS_NAME) @implementation CLS_NAME \
+(instancetype) sharedInstance \
{ \
static id instance; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
instance = [self new]; \
}); \
return instance; \
} \
@end \
在你的标题中:
SINGLETON_INTERFACE_START(Test)
@property (atomic, assign) NSUInteger value;
SINGLETON_INTERFACE_END(Test)
在你的.m
中:
SINGLETON_IMPLEMENTATION(Test)
并使用它(是的,可以产生更多的病):
TestGlobal().value = 1;
int i = TestGlobal().value;
或者“更好的”Objective-C 方式:
[Test sharedInstance].value = 1;
int i = [Test sharedInstance].value;
您甚至可以(美国队现在生病了)为界面中的属性设置一个#define
。
请注意,我已将 @interface
中的 @property
定义保留为 atomic
,因为 OP 似乎喜欢使用 @同步
。这是不需要的,因为它们被设置为atomic
。
我知道OP想要类“属性”(只是说这让我颤抖),但还有其他更好选择!
关于objective-c - 如何在 Objective-C 中创建可重用的类级属性构造?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23279603/