Пример кода Objective-C, который преднамеренно сообщает освобожденный объект

Я новичок в Objective -C и XCode, и приложение, которое я сейчас пишу, получает печально известную EXC_BAD_ACCESS ошибка.

Почти все рекомендуют начинать решать проблему с помощью NSZombies. Я думаю, что у меня работает NSZombies, но xcode не дает мне предупреждения о том, что зомби были отправлены сообщения, когда мое приложение зависало.

Прежде чем я продолжу свою отладку, я хотел бы запустить некоторый код, который наверняка приведет к отправке сообщения зомби (выделенный объект).

Что такое простой фрагмент кода, где сообщение отправляется на освобожденный объект, что вызывает сценарий, когда NSZombies должен предупредить меня?

2 ответа

Решение

Для не ARC-кода:

- (IBAction) messageZombie:(id)sender {
    id a = [[NSObject alloc]init];
    [a release];
    NSLog(@"%@", [a description]);
}

Это даст вам EXC_BAD_ACCESS с отключенными зомби и сообщением "сообщение отправлено освобожденному экземпляру" с включенными зомби.

Если ваш проект использует ARC, то немного сложнее надежно вызвать сообщения для выделенных объектов (в конце концов, это и есть точка ARC).

Это работает:

- (IBAction) messageZombie:(id)sender {    
    id a = [[NSObject alloc]init];
    id __unsafe_unretained b =a;
    a=nil;
    NSLog(@"%@", [b description]);
}

Это, вероятно, не очень похоже на то, что делает ваш настоящий код, потому что, черт возьми, кто использует __unsafe_unretained, в любом случае? Но если вы просто хотите убедиться, что NSZombies включены правильно, это должен быть разумный контрольный пример.

Если вы ищете в своем коде подозрительные места, то наверняка поищите указатели __unsafe_unretained, хотя вы не найдете никаких *, и дважды проверьте, что правильные приведения используются для объектов CoreFoundation, которые приводятся к объектам Какао.

* Если ваш проект должен поддерживать версии OS X до 10.7 или версии iOS более ранние, чем 5.0, то вы не можете использовать __weak указатели, поэтому в таком проекте вы можете ожидать, что __unsafe_unretained используется чаще.

Вы можете создать объект CF, связать его с объектом Objective-C, затем освободить его и попытаться использовать соединенный мостом объект. Я думаю, что вы должны использовать __bridge чтобы заставить себя вести себя так, как ты хочешь.

Другие вопросы по тегам