The macro way...
NOTE: This is a bit horrible and I don't really recommend using this but was playing around with defining them in macros...
The caveat to this (aside from it not being very "nice") is that the setter method is of the form set_XXX:
format.
#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 \
Place the following in header files:
CLASS_INTERFACE(Test, value, int)
And this in the .m
files:
CLASS_IMPLEMENTATION(Test, value, int)
Then to use the Test
class:
[Test set_value:4];
int i = [Test value];
Again this is pretty horrible but would work...!
Edit:
With singletons
As mentioned in the comments I think the use of a singleton is better, which has made me write even more horrible code :(
Now we have (sick bag ready):
#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 \
In you headers:
SINGLETON_INTERFACE_START(Test)
@property (atomic, assign) NSUInteger value;
SINGLETON_INTERFACE_END(Test)
And in your .m
:
SINGLETON_IMPLEMENTATION(Test)
And to use this (yes more sick can be produced):
TestGlobal().value = 1;
int i = TestGlobal().value;
Or the "nicer" Objective-C way:
[Test sharedInstance].value = 1;
int i = [Test sharedInstance].value;
You could even (Team America amounts of sick right now) have a #define
for the properties in the interface.
Note that I've left the @property
definitions in the @interface
as atomic
because the OP seems to love using @synchronized
. This is not needed is they are set to atomic
.
And I know the OP wants class "properties" (just saying that makes me shiver), but there are other better options!