cocoa - How do I create a reusable class-level property construct in Objective-C? -


i'd have class-level properties, , found solution 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 

and you're able call through property accessors, so:

model.value = 1 model.value // => 1 

fantastic!

now, want make chunk of code reusable, in form of macro or meta-programming, takes property name , type. how can write it?

with example above, value , (int) (and model) should dynamic.

update

thanks @rich have this:

// 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 

one thing left done automatically capitalize method name passed macro, if @ possible.

but it's more succinct boilerplate stands!

the macro way...

note: bit horrible , don't recommend using playing around defining them in macros...

the caveat (aside not being "nice") setter method of 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 following in header files:

class_interface(test, value, int) 

and in .m files:

class_implementation(test, value, int) 

then use test class:

[test set_value:4]; int = [test value]; 

again pretty horrible work...!

edit:

with singletons

as mentioned in comments think use of singleton better, has made me write more horrible code :(

now 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 headers:

singleton_interface_start(test)  @property (atomic, assign) nsuinteger value;  singleton_interface_end(test) 

and in .m:

singleton_implementation(test) 

and use (yes more sick can produced):

testglobal().value = 1; int = testglobal().value; 

or "nicer" objective-c way:

[test sharedinstance].value = 1; int = [test sharedinstance].value; 

you (team america amounts of sick right now) have #define properties in interface.

note i've left @property definitions in @interface atomic because op seems love using @synchronized. not needed set atomic.

and know op wants class "properties" (just saying makes me shiver), there other better options!


Comments

Popular posts from this blog

java - Intellij Synchronizing output directories .. -

git - Initial Commit: "fatal: could not create leading directories of ..." -