EXC_BAD_ACCESS для объекта просмотра предупреждений, который я сохранил, использовал, а затем выпустил - PullRequest
0 голосов
/ 21 октября 2011

Я знаю, что это распространенная проблема, поэтому мне нужно объяснение, чтобы у меня не возникало этой проблемы. В моем заголовочном файле я определил UIAlertView и сохранил его, как показано:

@interface myController {
    UIAlertView *alert;
}

@property (nonatomic, retain) UIAlertView *alert;

В моей реализации я использую и повторно использую это предупреждение следующим образом:

@synthesize alert;

 ...

    if (self.alert != nil) {
        [self.alert release];
    }

    self.alert = [[UIAlertView alloc] initWithTitle:title 
                                       message:message
                                      delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles: @"Ok To Send", nil];

    [self.alert show];

Я также сообщаю об этом в моем dealloc.

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

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

Пожалуйста, помогите мне понять, что я неправильно понимаю.

Ответы [ 3 ]

1 голос
/ 21 октября 2011

Похоже, вы дважды сохраняете свое предупреждение! self.alert выполняет сохранение, ваш объект уже имеет значение retainCount, равное 1, поскольку он был создан с помощью alloc init

Попробуйте это:

//if (self.alert != nil) {
//    [self.alert release];
//}

self.alert = nil;

alert = [[UIAlertView alloc] initWithTitle:title 
                                   message:message
                                  delegate:self
cancelButtonTitle:@"Cancel" otherButtonTitles: @"Ok To Send", nil];

[self.alert show];

вместо этого!

1 голос
/ 21 октября 2011

@property с указанным retain реализовано примерно так ...

-(void)setAlert:(UIAlertView*)alert
{
        if (self->alert != alert)
        {
                [self->alert release];
                self->alert = [alert retain];
        }
}

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

Кроме того, так как для @property установлено значение retain, вы должны autorelease перед присвоениемсвойство:

self.alert = [[[UIAlertView alloc] initWithTitle:title 
                                         message:message
                                        delegate:self cancelButtonTitle:@"Cancel"  
                               otherButtonTitles: @"Ok To Send", nil] autorelease];

[self.alert show];
1 голос
/ 21 октября 2011

Ваша собственность сохраняется.Поэтому, когда вы устанавливаете с собой. * Оно сохраняется для вас.Точно так же, когда вы устанавливаете для свойства nil или другой объект, он освобождает старый объект свойства.

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