我有很多方法可以重复这个简单的样板:
- (id)myObject {
if(!_myObject) {
self.myObject = [_myObject.class new];
}
return _myObject;
}
所以我想用一个简单的宏替换它:
#define default_init(instance) \
if(!instance) instance = [instance.class new]; \
return instance;
所以我只需要打电话:
- (id)myObject {
default_init(_myObject);
}
上面的代码目前正在编译,但问题是宏直接设置了实例变量的值。相反,我想调用self.instance = value;
所以而不是
if(!instance) instance = [instance.class new];
我喜欢这样的东西;
if(!instance) self.instance = [instance.class new];
但显然目前的代码不允许这样做。我怎么能做到这样的事呢?
答案 0 :(得分:1)
使用此宏:
#define default_init(class, instance) \
if ( ! _##instance ) { \
self.instance = [class new] ; \
} \
return _##instance
我能够创建这个实例方法:
- (NSMutableArray*) myObject {
default_init(NSMutableArray, myObject) ;
}
我必须添加一个定义类的参数,因为_myObject
仍然是nil
,因此_myObject.class
是nil
。
This StackOverflow question和this Cprogramming page建议在do {...} while(0)
中包装您的多行宏:
#define default_init(class, instance) \
do { \
if ( ! _##instance ) { \
self.instance = [class new] ; \
} \
return _##instance ; \
} while(0)
如果你真的想要,你可以创建一个定义整个方法的宏:
#define default_getter(class, instance) \
- (class*) instance { \
if ( ! _##instance ) { \
self.instance = [class new] ; \
} \
return _##instance ; \
}
然后使用它:
default_getter(NSMutableArray, myObject)
答案 1 :(得分:0)
我通常声明属性:
而不是构建getter方法的宏@interface Instance : NSObject
@property NSMutableArray* myObject ;
@end
并覆盖- init
以初始化属性:
- (id) init {
self = [super init] ;
if ( self ) {
self.myObject = [NSMutableArray new] ;
}
return self ;
}
答案 2 :(得分:0)
好的,这是我的看法。
注意:这样做只是为了看看是否可以完成。我认为在运输代码中使用它不是一个好主意。
首先从libextobjc导入#import "EXTRuntimeExtensions.h"
。然后:
#define underize(name) _##name
#define property_type(property) \
property_attr(property)->objectClass
#define property_attr(propertyName) \
ext_copyPropertyAttributes(class_getProperty(self.class, # propertyName))
#define default_init(propertyName) \
- (id)propertyName { \
if(!underize(propertyName)) self.propertyName = [property_type(propertyName) new]; \
return underize(propertyName); \
} \
然后说你有一个财产:
@property (nonatomic) NSArray *myArray;
你可以这样做:
default_init(myArray);
这会创建一个默认的getter。