Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@darionco
Created July 25, 2014 19:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darionco/03649feeee57f86fee3f to your computer and use it in GitHub Desktop.
Save darionco/03649feeee57f86fee3f to your computer and use it in GitHub Desktop.
Simple way to create "static properties" in Objective-C
//
// 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