Отправка релиза в NIL в Objective-c - PullRequest
0 голосов
/ 03 апреля 2011

Может кто-нибудь объяснить мне вывод этой программы на компьютере Mac, а затем на устройстве iphone.

Я создаю тривиальный класс Foo, который ничего не содержит, Foo.h:

#import <Foundation/Foundation.h>

@interface Foo : NSObject {

}

@end

и Foo.m:

#import "Foo.h"

@implementation Foo

@end

Для тестирования на Mac я использую этот main.m:

#import "Foo.h"

int main(int argc, const char *argv[]) {

  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Foo *myFoo; 

    [myFoo description];
    printf("%p\n", myFoo);
    [myFoo release];

    [pool drain];

    return 0;
}

Вывод этой программы:

0x0

Но на iphone он падает напрямую.

Спасибо.

Ответы [ 3 ]

8 голосов
/ 03 апреля 2011

Вы не отправляете релиз в переменную nil.Как и в C,

Foo *myFoo; 

создает неинициализированную переменную стека, которая может содержать любое значение мусора.На вашем Mac это, вероятно, имеет значение 0 (ноль), в то время как на iPhone оно имеет другое значение, которое приводит к сбою.

1 голос
/ 03 апреля 2011

Суть в том, что эта строка:

Foo *myFoo;

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

Foo *myFoo = [[Foo alloc] init];

Дополнительно, эта строка:

[myFoo description];

Это вообще ничего не делает. Метод -description возвращает строку, но вы нигде не храните возвращенную строку и ничего не делаете с ней.

Я мог бы продолжить, но я не буду - я советую вам посетить сайт Apple и прочитать их учебник по Learning Objective-C , а также дополнительные статьи, на которые есть ссылки. Это будет гораздо более эффективным способом изучения языка, чем просто придумывание материала и ожидание того, что компилятор его поймет.

1 голос
/ 03 апреля 2011

В Objective-C, когда вы вызываете метод с нулевым указателем, ничего не происходит.

Но в приведенном выше коде вы не устанавливаете указатель на ноль, поэтому отправляете сообщение в ячейку памяти. Если ваше приложение не имеет доступа к этой ячейке памяти, оно завершится с сообщением EXC_BAD_ACCESS.

Добавление этого должно прекратиться, если произойдет сбой: Foo *myFoo = nil;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...