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

How to access named pipes using JavaScript in Firefox add-on? -

multithreading - OPAL (Open Phone Abstraction Library) Transport not terminated when reattaching thread? -

node.js - req param returns an empty array -