Я прочитал главу Apple «обмен сообщениями» из программирования с целью - c и получил несколько вопросов о себе и супер. Насколько мне известно, когда компилятор находит какое-либо сообщение, он переводит его в objc_msgSend с двумя скрытыми параметрами - получатель, селектор и переменные аргументы для селектора. например [self test]
будет примерно так:
objc_msgSend(self, @selector(test));
если в таблице отправки получателя нет реализации метода, то функция попытается найти реализацию в суперклассах. super - это просто флаг для компилятора, чтобы начать поиск реализации метода в суперклассе текущего объекта, и в документации Apple говорится, что когда компилятор находит "super", он переводит его примерно так:
struct objc_super mySuperClass = {
self,
[self superclass]
};
objc_msgSendSuper(&mySuperClass, @selector(forwardedMethod));
Я сделал проект с 3 классами, каждый из которых наследуется от другого.
@interface FirstClass : NSObject
- (void)forwardMethod;
@end
@interface SecondClass : FirstClass
@end
@interface ThirdClass : SecondClass
@end
Я создал экземпляр третьего класса в моем корневом контроллере представления и вызвал его метод под названием «forwardMethod». Реализация :
//First Class
- (void)forwardMethod {
NSLog(@"Base class reached");
}
//SecondClass imp
- (void)forwardMethod {
NSLog(@"second class");
[super forwardMethod];
}
//ThirdClass imp
- (void)forwardMethod {
NSLog(@"third class");
[super forwardMethod];
}
Все работает нормально. Но потом я решил интерпретировать компилятор:
//First Class
- (void)forwardMethod {
NSLog(@"Base class reached");
}
//SecondClass imp
- (void)forwardMethod {
NSLog(@"second class");
struct objc_super mySuperClass = {
self,
[self superclass]
};
objc_msgSendSuper(&mySuperClass, @selector(forwardMethod));
}
//ThirdClass imp
- (void)forwardMethod {
NSLog(@"third class");
struct objc_super mySuperClass = {
self,
[self superclass]
};
objc_msgSendSuper(&mySuperClass, @selector(forwardMethod));
}
Что приводит к рекурсивному вызову второго класса «forwardMethod». Я создаю структуру в 'forwardMethod' во втором классе, используя self и [self superclass], но self является третьим классом, и
мой суперкласс всегда будет "вторым классом". Может быть, я делаю что-то не так, но как мне добраться до «метода пересылки» базового класса?