[[SelectorDemo new]TestParentMethod] [SelectorDemo new] [SelectorDemo new] [SelectorDemo new] [SelectorDemo new] [SelectorDemo new] [SelectorDemo new] [SelectorDemo new] What happens?

#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");
    
}


Copy the code

The first thing to understand is that after the method is switched between A and B, calling A is actually calling B, and the same thing is true here, calling TestParentMethod is actually calling SubMethod, and calling TestParentMethod in SubMethod is calling itself again, So you get stuck in a loop.

  [self performSelector:@selector(log)];
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
            [self performSelector:@selector(log) withObject:nil afterDelay:2];
    });
    
    - (void)log{
    NSLog(@"ogogogoogog");
}
Copy the code

The second one will not print because it requires timer support for delayed operations, and runloop for child threads is disabled by default.

- (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");
}
Copy the code

After printing “1”, it will crash, because the whole task is in the serial queue of the main thread, the serial queue FIFO, and now the task in the queue is executing viewdidLoad, execute to the dispatch_sync line, synchronization will block the current thread, and wait for the task in the block to complete before proceeding. Tasks in the block are added to the main queue and wait for the viewDidLoad method in the main queue to complete before they can proceed. This creates a waiting for each other, deadlock.

If it’s a parallel queue

 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]);
           });
       });
Copy the code

Fifo is not used in the concurrent queue, q first adds a large block, and then synchronization adds another block. After printing the first block, sync will still block the current thread and wait for the next block to finish executing. The block is in a concurrent queue, so it can be directly executed. There is no need to wait for the first block to complete.

Let’s look at this example

dispatch_async(dispatch_get_global_queue(0, 0), ^{
     NSLog(@"- 1");
     dispatch_sync(dispatch_get_main_queue(), ^{
         NSLog(@"- 2");
     });
     NSLog(@"- 3");
 });
 NSLog(@"- 4");
  while (YES) {
      
  }
Copy the code

I print 4, I print 1, and THEN I don’t print. Because a block waits until the last task on the main thread completes, while a while causes the outside task to never finish.