2012-04-01 1 views
8

Я прочитал вопрос ниже, и история КАЖЕТСЯ просто:Что такое "супер" в Objective-C? (self! = super)?

What exactly is super in Objective-C?

Еще ...

- (id) init 
{ 
    NSLog(@"self=%p, super=%p", self, super); 
} 

Это печатает "я = 0xa83dc50, супер = 0xbfffe8d0" , Адреса НЕ ТАКОЕ ???!?!?

Этот второй адрес выглядит как «особое значение» или что-то в этом роде. Что это значит?

Благодаря bbum, указав, что это значение является адресом стека специальной структуры, используемой компилятором для реализации «супер» поведения.


Я могу назвать [супер INIT] и вызов, кажется, работает, или, по крайней мере, ничего не взорвется ... не сразу. Вызов [((id) 0xbfffe8d0) init] терпит неудачу с EXC_BAD_ACCESS.

Тогда есть ДЕЙСТВИТЕЛЬНАЯ ВЕРСИЯ часть ..... У меня есть фрагмент кода, который по непонятной причине генерирует исключение «NSGenericException: collection был изменен, будучи перечисляемым». Внутри DIFFERENT объекта (в основном это оболочка с указателем на NSEnumerator), комментируя вызов «[super init]», исключение не происходит. Если бы я мог, я бы потратил $$$ вознаграждение за ответ на этот ум-изгиб.

«id sups = (id) 0xbfffe8d0» ... это также приводит к тому, что «коллекция модифицирована». ... WTF? Хорошо, таким образом я отправляю 2-й вопрос для этого bizzariotity ...


Первоначально я приехал сюда с одним из этих «странных Симптомов» ошибок, которые оказались совершенно не связан (типичной для таких вещей) : Does casting an address to (id) have side-effects??? Is Address 0xbfffe8d0 special? (fixed: issue was with _NSCallStackArray)

Однако содержание выше строки все еще актуально, и ответ по-прежнему превосходный. Прочтите, если вы хотите понять ObjC чуть глубже.

+2

Помимо ваших других проблем, 0xbfffe8d0 является, по-видимому, кодовым адресом, но нет никаких оснований ожидать, что он будет одним и тем же из одного компилята к другому. Выделение этого буквального значения указателю в основном просто создает указатель из случайного числа. –

+0

Фактически, это адрес стека, который не совпадает с адресом кода. Это не то же самое от одного прохода к следующему! –

+0

Адрес стека не совпадает с одним мгновением до следующего в том же запуске. –

ответ

15

Вы баловаться с человека за занавесом, и он наказывает тебя за это ... :)

super немного магии компилятора, на самом деле. Когда вы скажете [super doSomething], компилятор выдает вызов objc_msgSendSuper() вместо objc_msgSend(). Большую часть времени - есть некоторые особые случаи.

В целом, вы должны обрабатывать super как только для вызова методов. Он никогда не должен храниться нигде и никогда не должен считаться чем-то , но - это целевое выражение для обмена сообщениями.

Фактически, использование super, требующее хранения, должно быть отмечено компилятором.

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

+0

Хех, «возиться с человеком за занавеской» :) Я отправил второй вопрос с более подробной информацией об этой ошибке. –

+6

Если вам интересно, 'super' реализуется (или используется как) как указатель на структуру. Структура содержала два элемента, первая из которых была «self», а вторая была суперклассом, в котором говорится о том, в каком классе будет запускаться класс. – ughoavgfhw

+0

AH! Это объясняет странную ценность. Это адрес стека той фанковой структуры, о которой вы упоминаете. –

Смежные вопросы