1.有两个类SelectorDemo有一个方法TestParentMethod,SubSelector有个SubMethod方法,现在进行方法交换,交换完了,调用 [[SelectorDemo new]TestParentMethod]; 会出现什么情况?
#import "SubSelector.h"
#import "SelectorDemo.h"
#import <objc/runtime.h>
@implementation SubSelector
+ (void)load
{
Method originMethod = class_getInstanceMethod([SelectorDemo class], @selector(TestParentMethod));
Method replaceMethod = class_getInstanceMethod([self class], @selector(SubMethod));
method_exchangeImplementations(originMethod, replaceMethod);
}
- (void)SubMethod {
// [self TestParentMethod];
[[SelectorDemo new]TestParentMethod];
NSLog(@"sub class method call success");
}
首先要明白,方法交A 和B换完后,调用A实际是调用B,这里也是一样,调用TestParentMethod实际是调用SubMethod,而SubMethod方法里又调用了TestParentMethod 相当于又调用了本身,这样就会陷入死循环。
[self performSelector:@selector(log)];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self performSelector:@selector(log) withObject:nil afterDelay:2];
});
- (void)log{
NSLog(@"ogogogoogog");
}
第二个不会打印,因为有延时操作,需要定时器支持,而子线程的runloop默认是不开启的。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLog(@"1");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"2");
});
NSLog(@"3");
}
打印完1后会crash,因为整个任务是在主线程的串行队列,串行队列FIFO, 现在队列中在执行的任务是viewdidload方法,执行到dispatch_sync这一行,同步会阻塞当前线程,需要去等待block中的任务执行完成再往下进行,而block中的任务被加到主队列,需要等待主队列中的viewdidload方法执行完,才能往下执行。这样就产生了互相等待,死锁。
如果是并行队列呢
dispatch_queue_t q = dispatch_queue_create("hhhhh", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(q, ^{
NSLog(@" %@----111", [NSThread currentThread]);
dispatch_sync(q, ^{
NSLog(@" %@----2222", [NSThread currentThread]);
});
});
并发队列不用fifo,q中先添加了一大的block,然后同步又添加了一个block,打印完第一个打印,遇到sync依然会阻塞当前线程,等待下个block执行完再返回,block所在的是个并发队列,所以可以直接执行,并不需要等待第一个block执行完成。
再看这个例子
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"----1");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"----2");
});
NSLog(@"---3");
});
NSLog(@"---4");
while (YES) {
}
先打印4,再打印1,最后不打印了。因为block的任务需要等待主线程的上个任务执行完才行,而while导致,外面的任务永远执行不完。