1. Runloop
CFRunLoopRef CFRunLoopGetCurrent(void) {
CF_EXPORT CFRunLoopRef _CFRunLoopGet0(pthread_t t) {
// 一个 线程 对应 一个 runloop
CFRunLoopRef loop = (CFRunLoopRef)CFDictionaryGetValue(__CFRunLoops, pthreadPointer(t));
-
RunLoop 的本质是什么?
- 就是一个 while循环,可以一直保活;
- 内核态 => 用户态; 用户态 到 内核态的切换;
-
Runloop和线程是什么关系?
struct __CFRunLoop { pthread_t _pthread; CFMutableSetRef _commonModes; CFMutableSetRef _commonModeItems; CFRunLoopModeRef _currentMode; CFMutableSetRef _modes; };
-
Runloop的底层数据结构是什么样的?有几种 运行模式(mode)?每个运行模式下面的 CFRunloopMode 是哪些?他们分别是什么职责?
- 运行模式:
- NSDefault
- UITracking
- UIInitialization
- GSEventReceive : 系统内部的,我们用不到
- NSRunloopCommonModes
- Runloop 的监听状态有哪几种?
- Entry
- _objc_autoreleasePoolPush: -2147483647,优先级最高
- berforeTimer
- beforeSouce
- beforeWaiting
- CoreAnimation::commit (setNeedsLayout/setNeedsDisplay)
- _objc_autoreleasePoolPop()
- _objc_autoreleasePoolPush()
- afterWaiting
- exit
- _objc_autoreleasePoolPop()
- Runloop 的工作流程大概是什么样的?
https://juejin.cn/post/7068159603158024228

- Runloop 有哪些应用?
- 创建一个保活线程去处理一个事件
[[NSThread alloc] initWithTarget:[self class] selector:@selector(startLoop) object:nil];
+ (void)startLoop {
@autoreleasepool {
// 创建context
CFRunLoopSourceContext context = {0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
CFRunLoopSourceRef source = CFRunLoopSourceCreate(NULL, 0, &context);
// 创建source
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
CFRelease(source);
while (kCFRunLoopRunStopped != CFRunLoopRunInMode(
kCFRunLoopDefaultMode, ((NSDate *)[NSDate distantFuture]).timeIntervalSinceReferenceDate, NO)) {
NSLog(@"not reached assertion");
}
}
}
- 卡顿检测
- (void)beginMonitor {
self.isMonitoring = YES;
//监测 CPU 消耗
self.cpuMonitorTimer = [NSTimer scheduledTimerWithTimeInterval:3
target:self
selector:@selector(updateCPUInfo)
userInfo:nil
repeats:YES];
//监测卡顿
if (runLoopObserver) {
return;
}
dispatchSemaphore = dispatch_semaphore_create(0); //Dispatch Semaphore保证同步
//创建一个观察者
CFRunLoopObserverContext context = {0,(__bridge void*)self,NULL,NULL};
runLoopObserver = CFRunLoopObserverCreate(kCFAllocatorDefault,
kCFRunLoopAllActivities,
YES,
0,
&runLoopObserverCallBack,
&context);
//将观察者添加到主线程runloop的common模式下的观察中
CFRunLoopAddObserver(CFRunLoopGetMain(), runLoopObserver, kCFRunLoopCommonModes);
//创建子线程监控
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//子线程开启一个持续的loop用来进行监控
while (YES) {
// 88 毫秒的一个超时
long semaphoreWait = dispatch_semaphore_wait(dispatchSemaphore, dispatch_time(DISPATCH_TIME_NOW, STUCKMONITORRATE * NSEC_PER_MSEC));
if (semaphoreWait != 0) {
if (!runLoopObserver) {
timeoutCount = 0;
dispatchSemaphore = 0;
runLoopActivity = 0;
return;
}
//两个runloop的状态,BeforeSources和AfterWaiting这两个状态区间时间能够检测到是否卡顿
if (runLoopActivity == kCFRunLoopBeforeSources || runLoopActivity == kCFRunLoopAfterWaiting) {
//出现三次出结果
if (++timeoutCount < 3) {
continue;
}
// NSLog(@"monitor trigger");
// 打印堆栈
} //end activity
}// end semaphore wait
timeoutCount = 0;
}// end while
});
}
2. Runtime
2.1. 数据结构
// 对象结构体
struct objc_object {
Class _Nonnull isa; OBJC_ISA_AVAILABILITY;
};
// 实现了 objc_object 声明方法
struct objc_class : objc_object {
// Class ISA; // 8字节
Class superclass; // 8字节
cache_t cache; // 16字节
class_data_bits_t bits; // objc_class的基地址
}
// bucket => [sel => imp]
struct cache_t {
explicit_atomic<uintptr_t> _bucketsAndMaybeMask; // 8字节
union { // 8字节
struct {
explicit_atomic<mask_t> _maybeMask; //4字节
uint16_t _occupied;// 4字节
};
explicit_atomic<preopt_cache_t *> _originalPreoptCache;
};
}
struct class_data_bits_t {
uintptr_t bits; // 8字节
}
// 精简过的isa_t共用体
union isa_t
{
isa_t() { }
isa_t(uintptr_t value) : bits(value) { }
Class cls;
uintptr_t bits;
#if SUPPORT_PACKED_ISA
# if __arm64__
# define ISA_MASK 0x0000000ffffffff8ULL
# define ISA_MAGIC_MASK 0x000003f000000001ULL
# define ISA_MAGIC_VALUE 0x000001a000000001ULL
struct {
uintptr_t nonpointer : 1;
uintptr_t has_assoc : 1;
uintptr_t has_cxx_dtor : 1;
uintptr_t shiftcls : 33; // MACH_VM_MAX_ADDRESS 0x1000000000
uintptr_t magic : 6;
uintptr_t weakly_referenced : 1;
uintptr_t deallocating : 1;
uintptr_t has_sidetable_rc : 1; // 引用计数表
uintptr_t extra_rc : 19; // 引用计数
# define RC_ONE (1ULL<<45)
# define RC_HALF (1ULL<<18)
};
# elif __x86_64__
# define ISA_MASK 0x00007ffffffffff8ULL
# define ISA_MAGIC_MASK 0x001f800000000001ULL
# define ISA_MAGIC_VALUE 0x001d800000000001ULL
struct {
uintptr_t nonpointer : 1;
uintptr_t has_assoc : 1;
uintptr_t has_cxx_dtor : 1;
uintptr_t shiftcls : 44; // MACH_VM_MAX_ADDRESS 0x7fffffe00000
uintptr_t magic : 6;
uintptr_t weakly_referenced : 1;
uintptr_t deallocating : 1;
uintptr_t has_sidetable_rc : 1;
uintptr_t extra_rc : 8;
# define RC_ONE (1ULL<<56)
# define RC_HALF (1ULL<<7)
};
# else
# error unknown architecture for packed isa
# endif
#endif

字节对齐: 16字节对齐
- malloc_size: 分配内存 16字节对齐
- class_getInstanceSize: 真实的大小
NSObject * obj = [[NSObject alloc]init];
NSLog(@"obj = %d,%d,%d",sizeof(obj),class_getInstanceSize([NSObject class]),malloc_size((__bridge const void *)(obj))); //8,8,16
super关键字
struct objc_super {
id object;
id superClass;
};
// objc_msgSendSuper( objc_super的结构体, sel_registerName("test") )
[super test]
2.2 方法调用
- 先找isa指针
- 再找superClass
下面这种图非常经典
[obj iskindof:Class]
[obj isMemberof: Class]
方法调用

网友评论