управление памятью, должен ли в этом случае использоваться релиз?

Учитывая следующий фрагмент кода внутри метода;

NSBezierPath * tempPath = [NSBezierPath bezierPathWithOvalInRect:pathRect];
            [tempPath retain];
            [path release];
            [self setPath:tempPath];

Я ответственен за выпуск tempPathили это будет сделано для меня?
SetPath @synthesized, так что я, вероятно, смогу также опустить [path release]?

Я знаю, что лучший способ сделать это просто;

[path appendBezierPathWithOvalInRect:pathRect];

Но, будучи новичком в Objective C и Cocoa, я пытаюсь понять, как все складывается вместе.

--- ДОБАВЛЕННОЕ СОДЕРЖАНИЕ

Оставляя [tempPath retain]результаты в сбое в NSViewобъекте, который использует пути.
Результат от отладчика:

(gdb) po [0x145dc0 path]

Program received signal EXC_BAD_ACCESS, Could not access

Память. Причина: KERN_PROTECTION_FAILURE по адресу: 0x00000021 0x93c56688 в objc_msgSend ()



КОНФЕССИЯ ВИНА - моя ошибка. Надеюсь, кто-то еще получит что-то полезное от моей ошибки. Я использовал assignвместо retainв @propertyдекларации. Исправление заставило код работать как ожидалось.

СПАСИБО ЗА ПОМОЩЬ, РЕБЯТА

13.12.2008 01:28:27
3 ОТВЕТА
РЕШЕНИЕ

Если pathпеременная экземпляра поддерживает -setPath:метод, то нет, вам абсолютно не следует выпускать ее вне вашего -deallocметода. Вам не нужно вручную сохранять ваш tempPathобъект, так как вы используете аксессор для сохранения этого объекта. -setPath:В этом случае ваши методы доступа -initи -deallocметоды должны быть единственными методами, которые вы вызываете, -retainи -releaseдля переменных вашего экземпляра.

Ваш код работает так же, как этот, и с меньшей вероятностью утечки памяти:

NSBezierPath *tempPath = [NSBezierPath bezierPathWithOvalInRect:pathRect];
[self setPath:tempPath];

Так как -bezierPathWithOvalInRect:метод возвращает автоматически выпущенный объект и ваш аксессор сохранит его, вам больше ничего не нужно делать с ним.

3
13.12.2008 01:41:12
Спасибо, Эшли. Если я опускаю сохранение, программа падает позже в объекте NSView, который использует пути.
Joe 13.12.2008 01:47:53
@Ashley: Как вы узнали, что NSBezierPath bezierPathWithOvalInRect: вернул объект с автоматическим освобождением?
Brett 16.08.2012 05:41:39

Вам не нужно освобождать tempPath.

Вы также можете опустить [tempPath retain]и [path release]. Об этом заботятся, синтезируя метод набора.

1
13.12.2008 01:40:40

Давайте посмотрим на это по-другому:

Если бы вы не использовали синтезированные средства доступа, вы бы написали их сами. В своих простейших формах они выглядят так:

- (NSBezierPath *) path {
    return path;
}

- (void)setPath:(NSBezierPath *)newPath {
    if (path == newPath) {
        // both objects have the same pointer so are the same.
        return;
    }

    [path release];
    path = [newPath retain];
}

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

self.path = [NSBezierPath bezierPathWithOvalInRect:pathRect];
1
13.12.2008 01:55:32