幾個常用宏

懶加載宏

在創建各種子視圖時,我們習慣將這些子視圖定義爲對象屬性,然後通過屬性的獲取(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);
發佈了40 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章