Отказ от ответственности: этот вопрос носит чисто теоретический характер, поэтому, пожалуйста, не спрашивайте меня, почему я это делаю.
Если у меня есть следующий код:
- (void) beginCatastrophe {
double delayInSeconds = 3.5;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_global_queue(0, 0), ^(void){
Class cls = [self class];
IMP replacement = class_getMethodImplementation(cls, @selector(fooReplacement:));
Method fooMethod = class_getInstanceMethod(cls, @selector(foo:));
method_setImplementation(fooMethod, replacement);
});
[self foo:1];
}
- (void) fooReplacement:(unsigned) x {}
- (void) foo:(unsigned) x {
[self foo:++x];
}
И где-то еще в моем коде я звоню -beginCatastrophe
Это приводит к ошибке "слишком много рекурсии". Почему?
Я подтвердил, что код Swizzling работает через 2
секунд, но не дольше, чем
что.
Однако, если я сделаю что-то вроде этого:
- (void) beginCatastrophe {
double delayInSeconds = 3.5;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_global_queue(0, 0), ^(void){
Class cls = [self class];
IMP replacement = class_getMethodImplementation(cls, @selector(fooReplacement:));
Method fooMethod = class_getInstanceMethod(cls, @selector(foo:));
method_setImplementation(fooMethod, replacement);
});
[self foo:nil];
}
- (void) fooReplacement:(id) x {
printf("%s", _cmd);
}
- (void) foo:(id) x {
[self performSelector:_cmd withObject:x afterDelay:0.00001];
}
Это, конечно, прекрасно работает, независимо от того, как долго я делаю delayInSeconds
.