懒加载宏
在创建各种子视图时,我们习惯将这些子视图定义为对象属性,然后通过属性的获取(getter)方法实现子视图的懒加载。比如在控制器中我们需要创建一个自定会的子视图,经常会这样写:
- (UIView *)wrapperView {
if (!_wrapperView) {
_wrapperView = [[CustomView alloc] init];
}
return _wrapperView;
}
当需要创建多个自定义的子视图时,就需要重复写类似代码,我们可以通过定义一个宏来实现懒加载。
#ifndef JKLazyLoading
#define JKLazyLoading(_type_, _ivar_) \
- (_type_ *)_ivar_ { \
if (! _##_ivar_) { \
_##_ivar_ = [[_type_ alloc] init]; \
} \
return _##_ivar_; \
}
#endif
相应的上面通过宏可以如下调用:
JKLazyLoading(UIView, wrapperView)
self弱引用和强引用
在使用block时候,容易引起循环引用问题,为了打破循环引用,我们经常在进入block前先对self做一个弱引用,在block里为防止引用的弱self释放,进而对该弱引用的对象做一个强引用,如下:
__weak __typeof(self) weak_self = self;
[self doSomething:^{
__typeof(self) strong_self = weak_self;
...
}];
为了简化上面代码的书写,可以定义如下宏,
#ifndef weakify
#if DEBUG
#if __has_feature(objc_arc)
#define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;
#else
#define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;
#endif
#else
#if __has_feature(objc_arc)
#define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;
#else
#define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;
#endif
#endif
#endif
#ifndef strongify
#if DEBUG
#if __has_feature(objc_arc)
#define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;
#else
#define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;
#endif
#else
#if __has_feature(objc_arc)
#define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;
#else
#define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;
#endif
#endif
#endif
通过这个宏,上面代码可以简写为:
@weakify(self)
[self doSomething:^{
@strongify(self)
...
}];
关联对象宏
有时候我们会通过关联对象的方式为已有类添加属性,为避免记忆这些API的使用方式,这里给出一组宏可以简化动态属性的实现方式:
#ifndef JKDynamicProperty
#define JKDynamicProperty(_getter_, _setter_, _association_, _type_) \
- (void)_setter_ : (_type_ *)object { \
[self willChangeValueForKey:@#_getter_]; \
objc_setAssociatedObject(self, _cmd, object, OBJC_ASSOCIATION_ ## _association_); \
[self didChangeValueForKey:@#_getter_]; \
} \
- (_type_ *)_getter_ { \
return objc_getAssociatedObject(self, @selector(_setter_:)); \
}
#endif
按照如下方式使用该宏:
JKDynamicProperty(propetyName, setPropertyName, RETAIN_NONATOMIC, PropertyClass);