Проблема с выпуском Iphone - PullRequest
1 голос
/ 12 января 2011

у меня есть следующий код в .h

@property (nonatomic, copy) NSString *username;

Затем имя пользователя назначается таким образом, когда пользователь вводит текст в TextField:

self.username = textField.text;

И затем в методе dealloc я вызываю release:

NSLog(@"%d",[username retainCount]);
[username release];
NSLog(@"%d",[username retainCount]);

Но в консоли он печатает:

2011-01-11 23: 09: 52.468 IApp [2527: 307] 1
2011-01-11 23: 09: 52,480 IApp [2527: 307] 1

В чем проблема?

Спасибо

Ответы [ 4 ]

6 голосов
/ 12 января 2011

После освобождения объект уничтожается, поэтому вызов 'retaincount' во второй раз имеет неопределенное поведение

4 голосов
/ 12 января 2011

В чем проблема?

Проблема в том, что вы используете retainCount и ожидаете значимого результата.

Не звоните retainCount

Когда использовать -retainCount?

Выше есть некоторые хорошие детали. Как и один из ответов здесь:

https://stackoverflow.com/questions/4580684/common-programming-mistakes-for-objective-c-developers-to-avoid

<Ч />

Обратите внимание, что вы можете установить переменную окружения MallocScribble, и это приведет к заполнению выделенной памяти 0xaa байтами при выделении и 0x55 байтами при освобождении. Перед лицом вашего второго звонка на retainCount произойдет сбой.

3 голосов
/ 12 января 2011

Объекты не освобождаются сразу. Вероятно, должен быть цикл выполнения цикла, прежде чем объекты действительно будут освобождены.
Тем не менее, вызов retainCount действительно подлый. Пожалуйста, прочтите почему: Когда использовать -retainCount?

РЕДАКТИРОВАТЬ: @ kris-van-bael прокомментировал этот ответ - правильно - что на основе документации это не так. Поэтому я должен четко заявить, что то, что я написал здесь, основано на тестировании этой проблемы на симуляторе iOS - и это не то, как все это должно работать. Однако, похоже, что следующий код будет работать без ошибок:

@interface Test : NSObject { }
@property (retain, nonatomic) NSString *test;
@end

@implementation Test
@synthesize test;
@end

Тогда где-нибудь в вашем коде напишите:

Test* t = [[Test alloc] init];
t.test = @"Test1";

NSLog(@"%@", t.test);

[t release];

t.test = @"Test2";

NSLog(@"%@", t.test);    

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

3 голосов
/ 12 января 2011

Когда вы освобождаете в первый раз, счетчик сохранения равен 1. Поскольку память собирается быть освобождена, нет необходимости «уменьшать» счетчик хранения, поэтому основной код может просто пропустить шаг уменьшения и освободитьпамять.

Когда вы просматриваете счетчик сохранения во второй раз, вы смотрите на освобожденную память, которая небезопасна и потенциально может вернуть любое значение.Так как он сразу после release, память, вероятно, не была выделена для чего-то другого, но вы не должны получать к ней доступ независимо от этого.

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