- (void)test2
{
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
NSLog(@"1");
// 这句代码的本质是往Runloop中添加定时器
[self performSelector:@selector(test) withObject:nil afterDelay:.0];
NSLog(@"3");
// [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
});
}
- (void)test
{
NSLog(@"2");
}
如果 不添加 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 则 不会打印 2 因为 [self performSelector:@selector(test) withObject:nil afterDelay:.0]; 本质上在 runloop 里面添加了 timer runloop 如果 不runMode 则timer 不会执行[self performSelector:@selector(test) withObject:nil afterDelay:.0];
线程安全-同步线程-线程锁
OSSpinLock 使用方式
self.lock = OS_SPINLOCK_INIT;
- (void)drawMoney
{
// 加锁
OSSpinLockLock(&_lock1);
int oldMoney = self.money;
sleep(.2);
oldMoney -= 20;
self.money = oldMoney;
NSLog(@"取20,还剩%d元 - %@", oldMoney, [NSThread currentThread]);
// 解锁
OSSpinLockUnlock(&_lock1);
}
os_unfair_lock
不用的时候最好 销毁 相关的锁
调用的时候防止死锁
define PTHREAD_MUTEX_NORMAL 0
define PTHREAD_MUTEX_ERRORCHECK 1
define PTHREAD_MUTEX_RECURSIVE 2 // 递归锁 (递归调用的时候用 防止死锁)
define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL // 普通锁
控制台 命令 bt 打印 堆栈
// 保证调用频率和屏幕的刷帧频率一致,60FPS
self.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(linkTest)];
[self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
注意 CADisplayLink 和 timer 会对 target 进行强引用 可能造成循环引用()
NSProxy 基类 主要用于消息转发 他的大部分方法直接进行消息转发 例如
isKindOfClass
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
{
return [self.target methodSignatureForSelector:sel];
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
[invocation invokeWithTarget:self.target];
}