ARC, возвращающий объект из лучших методов метода (получение предупреждения об утечке памяти) - PullRequest
8 голосов
/ 08 января 2012

Я создавал пример проекта в xcode 4.2 и заметил, что новый проект был настроен с помощью ARC.

У меня есть метод, показанный ниже.Ранее я бы автоматически выпустил ячейку в методе и позволил бы представлению таблицы вызывающей стороны сохранить ячейку.С ARC автоматическое освобождение не было бы возможно,

- (UITableViewCell*) getCellForIndex:(int)index {

    UITableViewCell *cell =         
        [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];

    if (index == 0)
        cell.textLabel.text = profileToUse.name;
    if (index == 1)
        cell.textLabel.text = profileToUse.sex;
    if (index == 2)
        cell.textLabel.text = profileToUse.city;
    return cell;
}

Когда я запускаю инструмент анализа на приведенном выше коде, он говорит, что существует потенциальная утечка памяти объекта 'ячейка'.

Как должно быть написано выше с использованием ARC, чтобы предупреждение анализа исчезло?Что я делаю не так?

Спасибо.

Ответы [ 2 ]

5 голосов
/ 08 января 2012

Попробуйте переименовать метод в -cellForIndex :, методы с префиксом "get" имеют другое предполагаемое поведение в Какао.

(Также, возможно, -cellAtIndex: для согласования с NSArray и т. Д ...)

4 голосов
/ 09 января 2012

Ваш метод getCellForIndex: выделяет и возвращает объект, таким образом, он похож на прямой alloc (на самом деле ваш код - просто alloc с некоторой инициализацией).

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

Предположение можно изменить, добавив явный атрибут к вашему методу как в @interface, так и в @implementation:

- (UITableViewCell*) getCellForIndex:(int)index __attribute((ns_returns_retained))

ARC теперь будет знать, что право собственности на объект передано. Методы в семействах alloc, new и т. Д. Автоматически добавляют этот атрибут. Поскольку другие ответы предполагают, что вам может быть лучше переименовать ваш метод, newCellForIndex: может быть здесь уместным, поскольку new используется для комбинации alloc и init, что и делает ваш метод.

Кстати: изменение вашего второго и третьего if на else if сделает ваш алгоритм более понятным (и немного быстрее, но это не причина для этого).

Вопрос в комментарии:

ARC действительно вводит новые атрибуты и т. Д., Но также использует умозаключения и значения по умолчанию, так что если вы следуете обычным соглашениям о Какао, они вам не нужны слишком часто - YMMV, конечно ... В дополнение к документам Apple вы можете найти описание здесь .

...