看YYTransaction的说明为,创建一个YYTransaction实例,在main runloop休眠前执行传入的target对应的selector。主要功能就是添加target和selector,然后commit,等main runloop休眠前被调用。
那么有添加的地方,而没有删除的地方。
重点代码
实现这个类的功能的主要代码是
transactionSet = [NSMutableSet new];
CFRunLoopRef runloop = CFRunLoopGetMain();
CFRunLoopObserverRef observer;
observer = CFRunLoopObserverCreate(CFAllocatorGetDefault(),
kCFRunLoopBeforeWaiting | kCFRunLoopExit,
true, // repeat
0xFFFFFF, // after CATransaction(2000000)
YYRunLoopObserverCallBack, NULL);
CFRunLoopAddObserver(runloop, observer, kCFRunLoopCommonModes);
CFRelease(observer);
将需要回调的方法添加到CFRunLoopObserverRef中。
CFRunLoopGetMain
苹果不允许直接创建RunLoop,只提供了自动获取的函数:CFRunLoopGetMain()
和CFRunLoopGetCurrent()
。
CFRunLoopObserverCreate
创建一个基于回调函数的CFRunLoopObserver。
CF_EXPORT CFRunLoopObserverRef CFRunLoopObserverCreate(CFAllocatorRef allocator, CFOptionFlags activities, Boolean repeats, CFIndex order, CFRunLoopObserverCallBack callout, CFRunLoopObserverContext *context);
CFOptionFlags的枚举内容有:
/* Run Loop Observer Activities */
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
kCFRunLoopEntry = (1UL << 0),
kCFRunLoopBeforeTimers = (1UL << 1),
kCFRunLoopBeforeSources = (1UL << 2),
kCFRunLoopBeforeWaiting = (1UL << 5),
kCFRunLoopAfterWaiting = (1UL << 6),
kCFRunLoopExit = (1UL << 7),
kCFRunLoopAllActivities = 0x0FFFFFFFU
};
当在kCFRunLoopBeforeWaiting和kCFRunLoopExit条件时,将会执行YYRunLoopObserverCallBack函数。
CFRunLoopAddObserver
因为CFRunLoopObserver不能直接自动添加到RunLoop中,所以需要调用CFRunLoopAddObserver将observer添加到RunLoop中。
CFRelease(observer);
将observer添加到RunLoop后,需要将observer释放。
重载hash和isEqual方法
重载了NSObject的方法- (NSUInteger)hash
和- (BOOL)isEqual:(id)object
方法,因为在使用transactionSet(为NSMutableSet对象)进行添加对象时,需要进行判断新添加的对象是否与之前已经存在的重复。所以重载了方法,进行target和select的判断。
感谢席萍萍_developer的指点。
疑问
只有commit添加,但是没有删除。那么是不是在runloop中一直会repeat所有commit的方法。那是不是存在很多的无效操作。
// END 求高手赐教。