Created
July 25, 2014 19:50
-
-
Save darionco/03649feeee57f86fee3f to your computer and use it in GitHub Desktop.
Simple way to create "static properties" in Objective-C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// P2StaticProperties.h | |
// P2 | |
// | |
// Created by Dario Segura on 3/5/2014. | |
// | |
// | |
// Copyright 2014 Trompo Games Inc. | |
// | |
// Licensed under the Apache License, Version 2.0 (the "License"); | |
// you may not use this file except in compliance with the License. | |
// You may obtain a copy of the License at | |
// | |
// http://www.apache.org/licenses/LICENSE-2.0 | |
// | |
// Unless required by applicable law or agreed to in writing, software | |
// distributed under the License is distributed on an "AS IS" BASIS, | |
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
// See the License for the specific language governing permissions and | |
// limitations under the License. | |
// | |
// | |
/* | |
MACRO TO CREATE STATIC (CLASS LEVEL) PROPERTIES | |
NOTE: ARC Requires explicit __strong or __weak keywords in the macro ASSIGN variants instead of using the RETAIN variants (this will be fixed in a future version) | |
This macro is used as follows: | |
STATIC_PROPERTY_RW_ASSIGN(int, variableName, setVariableName) | |
where: | |
int -> type of variable to create | |
variableName -> the variable/property name. This is the name that will be user to access the variable through dot syntax (i.e. int i = ClassName.variableName) or by method calling (i.e. int i = [ClassName variableName]) | |
setVariableName -> the name of the setter to use. If the setter complies to the cocoa setter naming convetions it can be used as a property (i.e. ClassName.variableName = 5), otherwise the method has to be called (i.e. [ClassName setVariableName:5]) | |
The different variations of the macro are: | |
STATIC_PROPERTY_RW_ASSIGN for (readwrite, atomic, assign) properties | |
STATIC_PROPERTY_RW_RETAIN for (readwrite, atomic, retain) properties | |
STATIC_PROPERTY_RW_NONATOMIC_ASSIGN for (readwrite, nonatomic, assign) properties | |
STATIC_PROPERTY_RW_NONATOMIC_RETAIN for (readwrite, nonatomic, retain) properties | |
STATIC_PROPERTY_RO for (readonly) properties, a custom setter is needed a pointer to the variable can be accessed using the static method +(varType*)P2__varName__ptr | |
STATIC_PROPERTY_VO this only creates the variable aka the static method +(varType*)P2__varName__ptr | |
To declare the static properties in header files use: | |
STATIC_PROPERTY_DECL_RW to declare (readwrite) properties | |
STATIC_PROPERTY_DECL_RO to declare (readonly) properties | |
Please note that the declaration and implementation do not have to match i.e. a read only property can be declared in the header file (using STATIC_PROPERTY_DECL_RO) but a read/write property can be implemented in the source file (using any of the RW implementation macros like STATIC_PROPERTY_RW_RETAIN) | |
*/ | |
/* | |
readwrite, atomic, assign | |
*/ | |
#define STATIC_PROPERTY_RW_ASSIGN(__type__, __name__, __setter__) \ | |
+(__type__ *) P2__ ## __name__ ## __ptr \ | |
{ \ | |
static __type__ * __var__ = nil; \ | |
if (!__var__) \ | |
{ \ | |
__var__ = (__type__ *)calloc(1, sizeof(__type__ *)); \ | |
} \ | |
return __var__; \ | |
} \ | |
\ | |
+(__type__) __name__ \ | |
{ \ | |
return (*[self P2__ ## __name__ ## __ptr]); \ | |
} \ | |
\ | |
+(void) __setter__:(__type__)__name__ \ | |
{ \ | |
@synchronized(self) \ | |
{ \ | |
__type__ * __var__ = [self P2__ ## __name__ ## __ptr]; \ | |
(*__var__) = __name__; \ | |
} \ | |
} | |
/* | |
readwrite, atomic, retain | |
*/ | |
#define STATIC_PROPERTY_RW_RETAIN(__type__, __name__, __setter__) \ | |
+(__type__ *) P2__ ## __name__ ## __ptr \ | |
{ \ | |
static __type__ * __var__ = nil; \ | |
if (!__var__) \ | |
{ \ | |
__var__ = (__type__ *)calloc(1, sizeof(__type__ *)); \ | |
} \ | |
return __var__; \ | |
} \ | |
\ | |
+(__type__) __name__ \ | |
{ \ | |
return (*[self P2__ ## __name__ ## __ptr]); \ | |
} \ | |
\ | |
+(void) __setter__:(__type__)__name__ \ | |
{ \ | |
@synchronized(self) \ | |
{ \ | |
__type__ * __var__ = [self P2__ ## __name__ ## __ptr]; \ | |
[(*__var__) release]; \ | |
(*__var__) = [ __name__ retain ]; \ | |
} \ | |
} | |
/* | |
readwrite, nonatomic, assign | |
*/ | |
#define STATIC_PROPERTY_RW_NONATOMIC_ASSIGN(__type__, __name__, __setter__) \ | |
+(__type__ *) P2__ ## __name__ ## __ptr \ | |
{ \ | |
static __type__ * __var__ = nil; \ | |
if (!__var__) \ | |
{ \ | |
__var__ = (__type__ *)calloc(1, sizeof(__type__ *)); \ | |
} \ | |
return __var__; \ | |
} \ | |
\ | |
+(__type__) __name__ \ | |
{ \ | |
return (*[self P2__ ## __name__ ## __ptr]); \ | |
} \ | |
\ | |
+(void) __setter__:(__type__)__name__ \ | |
{ \ | |
__type__ * __var__ = [self P2__ ## __name__ ## __ptr]; \ | |
(*__var__) = __name__; \ | |
} | |
/* | |
readwrite, nonatomic, retain | |
*/ | |
#define STATIC_PROPERTY_RW_NONATOMIC_RETAIN(__type__, __name__, __setter__) \ | |
+(__type__ *) P2__ ## __name__ ## __ptr \ | |
{ \ | |
static __type__ * __var__ = nil; \ | |
if (!__var__) \ | |
{ \ | |
__var__ = (__type__ *)calloc(1, sizeof(__type__ *)); \ | |
} \ | |
return __var__; \ | |
} \ | |
\ | |
+(__type__) __name__ \ | |
{ \ | |
return (*[self P2__ ## __name__ ## __ptr]); \ | |
} \ | |
\ | |
+(void) __setter__:(__type__)__name__ \ | |
{ \ | |
__type__ * __var__ = [self P2__ ## __name__ ## __ptr]; \ | |
[(*__var__) release]; \ | |
(*__var__) = [ __name__ retain ]; \ | |
} | |
/* | |
readonly (for custom setter implementation) | |
*/ | |
#define STATIC_PROPERTY_RO(__type__, __name__) \ | |
+(__type__ *) P2__ ## __name__ ## __ptr \ | |
{ \ | |
static __type__ * __var__ = nil; \ | |
if (!__var__) \ | |
{ \ | |
__var__ = (__type__ *)calloc(1, sizeof(__type__ *)); \ | |
} \ | |
return __var__; \ | |
} \ | |
\ | |
+(__type__) __name__ \ | |
{ \ | |
return (*[self P2__ ## __name__ ## __ptr]); \ | |
} | |
/* | |
varonly (for custom getter/setter implementations) | |
*/ | |
#define STATIC_PROPERTY_VO(__type__, __name__) \ | |
+(__type__ *) P2__ ## __name__ ## __ptr \ | |
{ \ | |
static __type__ * __var__ = nil; \ | |
if (!__var__) \ | |
{ \ | |
__var__ = (__type__ *)calloc(1, sizeof(__type__ *)); \ | |
} \ | |
return __var__; \ | |
} | |
/* | |
MACRO TO DEFINE STATIC PROPERTIES IN @interface DECLARATIONS, IN CASE PROPERTIES ARE TO BE USED OUTSIDE THE IMPLEMENTATION | |
Usage: | |
STATIC_PROPERTY_DECL_RW(int, variableName, setVariableName) | |
where: | |
int -> type of variable to create | |
variableName -> the variable/property name. This is the name that will be user to access the variable through dot syntax (i.e. int i = ClassName.variableName) or by method calling (i.e. int i = [ClassName variableName]) | |
setVariableName -> the name of the setter to use. If the setter complies to the cocoa setter naming convetions it can be used as a property (i.e. ClassName.variableName = 5), otherwise the method has to be called (i.e. [ClassName setVariableName:5]) | |
*/ | |
/* | |
readwrite | |
*/ | |
#define STATIC_PROPERTY_DECL_RW(__type__, __name__, __setter__) \ | |
+(__type__) __name__; \ | |
+(void) __setter__:(__type__)__name__; | |
/* | |
readonly | |
*/ | |
#define STATIC_PROPERTY_DECL_RO(__type__, __name__) \ | |
+(__type__) __name__; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment