iOS最近碰到的几个问题

243 阅读2分钟

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导致,外面的任务永远执行不完。