简介:IOS 合理利用Runloop可高效率利用内存,优化程序性能。DWURunLoopWorkDistribution就是一个合理利用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,其中规定其唤醒条件kCFRunLoopBeforeWaiting即每当线程即将进入休眠状态时便可进行任务的执行。可通过下面方法添加任务
- (void)addTask:(DWURunLoopWorkDistributionUnit)unit withKey:(id)key;
将任务对应的添加到task 和 taskkeys数组数组中方便在注册方法中的callback中以待处理。
以上便是大致思路,关于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