DWURunLoopWorkDistribution 소스 판독

소개: IOS는 Runloop을 합리적으로 활용하여 메모리를 효율적으로 활용하고 프로그램 성능을 최적화한다.DWURunLoopWork Distribution은 runloop을 합리적으로 이용하여tableview를 효율적으로 표시하는 예이다.runloop뿐만 아니라 runtime의 일부 내용도 포함한다.
runloop 주요 방법
+(void)_registerRunLoopWorkDistributionAsMainRunloopObserver:(DWURunLoopWorkDistribution *)runLoopWorkDistribution;
static void _registerObserver(CFOptionFlags activities, CFRunLoopObserverRef observer, CFIndex order, CFStringRef mode, void *info, CFRunLoopObserverCallBack callback);
static void _runLoopWorkDistributionCallback(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info);
원본 코드를 보면 알 수 있듯이cell 이미지와 label을 분리하고 매번 runloop이 휴면 상태에 들어가기 전에 작업(task)을 처리하면 같은 라인을 합리적으로 활용하여 메모리를 절약할 수 있다.
세부 코드 분석
static void _registerObserver(CFOptionFlags activities, CFRunLoopObserverRef observer, CFIndex order, CFStringRef mode, void *info, CFRunLoopObserverCallBack callback) {
    CFRunLoopRef runLoop = CFRunLoopGetCurrent();
    CFRunLoopObserverContext context = {
        0,
        info,
        &CFRetain,
        &CFRelease,
        NULL
    };
    observer = CFRunLoopObserverCreate(     NULL,
                                            activities,
                                            YES,
                                            order,
                                            callback,
                                            &context);
    CFRunLoopAddObserver(runLoop, observer, mode);
    CFRelease(observer);
}
+ (void)_registerRunLoopWorkDistributionAsMainRunloopObserver:(DWURunLoopWorkDistribution *)runLoopWorkDistribution {
    static CFRunLoopObserverRef defaultModeObserver;
    _registerObserver(kCFRunLoopBeforeWaiting, defaultModeObserver, NSIntegerMax - 999, kCFRunLoopDefaultMode, (__bridge void *)runLoopWorkDistribution, &_defaultModeRunLoopWorkDistributionCallback);
}
기본 모드로 생성
runloopObserver, 깨우기 조건 kCFRunLoopBefore Waiting, 즉 라인이 휴면 상태에 들어갈 때마다 임무를 수행할 수 있도록 규정되어 있습니다.다음 방법으로 작업을 추가할 수 있습니다
- (void)addTask:(DWURunLoopWorkDistributionUnit)unit withKey:(id)key; 작업에 대응하는task와taskkeys수 그룹에 작업을 추가하면 등록 방법의 콜백에서 처리하기 쉽습니다.
이상은 대체적인 사고방식이다.cell의runtime 처리에 관해서는 여기서 더 이상 군말하지 않고 코드만 첨부한다
@implementation UITableViewCell (DWURunLoopWorkDistribution)

@dynamic currentIndexPath;

- (NSIndexPath *)currentIndexPath {
    NSIndexPath *indexPath = objc_getAssociatedObject(self, @selector(currentIndexPath));
    return indexPath;
}

- (void)setCurrentIndexPath:(NSIndexPath *)currentIndexPath {
    objc_setAssociatedObject(self, @selector(currentIndexPath), currentIndexPath, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

좋은 웹페이지 즐겨찾기