Неверное уменьшение количества ссылок и утечки памяти - PullRequest
0 голосов
/ 14 декабря 2011

С помощью 'Analyze' в dealloc я получаю: Неправильное уменьшение счетчика ссылок объекта, которому на данный момент не принадлежит вызывающая сторона

#import <AVFoundation/AVFoundation.h>
@interface XYZViewController : UIViewController
@property (retain) AVAudioRecorder  *recorder;
@end
@implementation XYZViewController
@synthesize recorder;
- (void) dealloc
{
    [self.recorder release];
    [super dealloc];
}
- (void) viewDidLoad
{
    NSURL *url = [NSURL fileURLWithPath:@"/dev/null"];
    NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys:
                          [NSNumber numberWithFloat: 44100.0],                 AVSampleRateKey,
                          [NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey,
                          [NSNumber numberWithInt: 1],                         AVNumberOfChannelsKey,
                          [NSNumber numberWithInt: AVAudioQualityMax],         AVEncoderAudioQualityKey,
                          nil];
    NSError *error;
    self.recorder = [[[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error] autorelease];
}
@end

это значит, что я не должен выпускать это?Кроме того, я попытался «профилировать» код и получил утечку памяти от [[[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error] autorelease], несмотря ни на что.

Ответы [ 2 ]

4 голосов
/ 14 декабря 2011

Вы должны выпустить ивар непосредственно, а не проходить через аксессор:

- (void)dealloc
{
    [recorder release];
    [super dealloc];
}

Вы не являетесь владельцем возвращенного объекта аксессора, поэтому не следует его отпускать.

1 голос
/ 16 декабря 2011

Вместо отправки -release объекту, возвращенному методом метода доступа к свойству, установите для самого свойства значение nil:

- (void)dealloc {
    self.recorder = nil;
    [super dealloc];
}

Компилятор будет знать, как поступить правильно, потому что вы указали семантику хранилища в объявлении свойства. Синтезирование свойства, объявленного с семантикой retain, фактически эквивалентно написанию следующих методов доступа:

- (AVAudioRecorder *)recorder {
    return recorder;
}

- (void)setRecorder:(AVAudioRecorder *)newRecorder {
    [newRecorder retain];
    [recorder release];
    recorder = newRecorder;
}

Когда вы пишете self.recorder = nil, компилятор переводит его в [self setRecorder:nil]. Таким образом, установка свойства на nil позволяет избежать как утечек памяти, так и висячих указателей, включает в себя меньшее количество шаблонов с вашей стороны и более четко выражает намерение кода.

Наконец, никогда не помешает перечитать Язык программирования Objective-C , в котором есть раздел по объявленным свойствам; и Расширенное руководство по программированию управления памятью , в котором подробно рассматриваются все различные подходы к управлению памятью.

...