чтобы получить объект класса суперкласса. @mindnoise

т[super init] сделать то же самое в категории в качестве подкласса? Если нет, то какая разница?

 albertamg29 мая 2011 г., 16:02
«Когда категория переопределяет унаследованный метод, метод в категории может, как обычно, вызывать унаследованную реализацию через сообщение super. Однако, если категория переопределяет метод, который существует в классе категории, нет способа вызвать оригинальная реализация. " изКак вы можете использовать категории.

Ответы на вопрос(1)

Решение Вопроса

вероятно, важно понять, как объект хранится во время выполнения. Есть объект класса1, которая содержит все реализации метода, и отдельно есть структура с хранилищем для переменных экземпляра. Все экземпляры класса совместно используют один объект класса.

Когда вы вызываете метод в экземпляре, компилятор превращает это в вызовobjc_msgSend; реализация метода ищется в объекте класса, а затем запускается с экземпляром в качестве аргумента.

Ссылка наsuper вступает в силу во время компиляции,не время выполнения. Когда ты пишешь[super someMethod]компилятор превращает это в вызовobjc_msgSendSuper вместо обычногоobjc_msgSend, Это начинает искать реализацию метода всуперкласса объект класса, а не объект класса экземпляра.2

Категория просто добавляет методы к объекту класса; это мало или не имеет отношения к подклассам.

Учитывая все это, если вы ссылаетесь наsuper внутри категории он действительно делает то же самое, что и внутри класса - реализация метода ищется на объекте классасуперкласс, а затем запустить с этим экземпляром в качестве аргумента.

Пост Итай отвечает на вопрос более прямо, но в коде:

@interface Sooper : NSObject {}
- (void) meth;
@end

@interface Sooper ()
- (void) catMeth;
@end

@interface Subb : Sooper {}
- (void) subbMeth;
@end

@interface Subb ()
- (void) catSubbMeth;
@end

@implementation Sooper
- (void) meth {
    [super doIt];    // Looks up doIt in NSObject class object
}

- (void) catMeth {
    [super doIt];    // Looks up doIt in NSObject class object
}
@end

@implementation Subb
- (void) subbMeth {
    [super doIt];    // Looks up doIt in Sooper class object
}

- (void) catSubbMeth {
    [super doIt];    // Looks up doIt in Sooper class object
}
@end

1 Посмотреть рецензию Грега Паркера[objc объясните]: классы и мета-классы

2Важно отметить, что метод не вызываетсяэкземпляр суперкласса. Здесь происходит разделение методов и данных. Метод по-прежнему вызывается в том же экземпляре, в котором[super someMethod] был написан, то есть экземпляр подкласса, используя данные этого экземпляра; он просто использует реализацию метода суперкласса.

Так что призыв к[super class] идет к объекту суперкласса, находит реализацию метода с именемclassи вызывает его в экземпляре, превращая его в эквивалент[self theSuperclassImplementationOfTheMethodNamedClass], Так как все, что делает этот метод, это возвращает класс экземплярана котором это называлось, вы не получите класс суперкласса, вы получите классself, В связи с этим, звоняclass является своего рода плохой проверкой этого явления.

Весь этот ответ полностью игнорирует различие между передачей сообщений / вызовом метода. Это важная особенность ObjC, но я думаю, что это, вероятно, будет просто грязным и без того неловким объяснением.

 Grady Player30 мая 2011 г., 01:19
как [[obj class] class] имеет данные экземпляра? Я хочу сказать, что компилятор не позволит мне получить доступ к информации ivar из метода класса. если это так, то как он знает, какой экземпляр использовать?
 Josh Caswell30 мая 2011 г., 01:13
поговорка[obj class] дает вам объект типаClass *, но класс этого объектасам, так[obj class] == [[obj class] class]
 Grady Player30 мая 2011 г., 01:08
спасибо, имеет смысл.
 Grady Player30 мая 2011 г., 00:58
так ли это, потому что данные для -класса хранятся в данных экземпляра подкласса? а не что-то вроде [[self class] classMethodforClass], тогда почему [[super class] class] все еще использует эти данные экземпляра, если это не метод класса суперкласса.
 Josh Caswell30 мая 2011 г., 01:07
Если вы вызываете метод, ссылаясь наself или жеsuper, передается данные текущего экземпляра, да. Разница лишь в том, какая реализация метода используется. Если вы позвоните[self doSomething] и текущий класс не реализован повторноdoSomethingто это эквивалентно[super doSomething], Единственная причина использоватьsuper это когда вам нужно вызвать реализацию суперкласса, обычно из переопределенного метода.

Ваш ответ на вопрос