Предупреждение «Потенциальная утечка объекта, размещенного на линии ...» при объявлении 2D-массива - PullRequest
1 голос
/ 12 апреля 2011

Первоначально я объявил двумерный массив следующим образом:

subUrb = [[NSArray alloc] initWithObjects:
     [[NSArray alloc] initWithObjects:ALL_SUBURBS_LABEL, @"East",@"South", @"West", @"North", nil] ,
     [[NSArray alloc] initWithObjects:ALL_SUBURBS_LABEL, @"Kuala Lumpur SubUrb1", @"Kuala Lumpur SubUrb2", nil],
     [[NSArray alloc] initWithObjects:ALL_SUBURBS_LABEL, @"Jakarta SubUrb1",nil],
     nil]; 

Но когда я пытаюсь «проанализировать» предупреждения проекта, у меня возникает три одинаковых типа проблем в этом куске кода - "потенциальная утечка объекта, расположенного в строке xxx"

Я заметил, что, чтобы избавиться от него, я должен написать вот что:

subUrb = 
    [[NSArray alloc] initWithObjects:
        [[[NSArray alloc] initWithObjects:ALL_SUBURBS_LABEL, @"East",@"South", @"West", @"North", nil] autorelease],
        [[[NSArray alloc] initWithObjects:ALL_SUBURBS_LABEL, @"Kuala Lumpur SubUrb1", @"Kuala Lumpur SubUrb2", nil] autorelease],
        [[[NSArray alloc] initWithObjects:ALL_SUBURBS_LABEL, @"Jakarta SubUrb1",nil] autorelease],
        nil];

Тогда яне получит никаких аналитических предупреждений.Но я не знаю, как это ... это не логично.Этот 2D-массив никогда не должен выпускаться в моем контроллере, фактически, весь 2D-массив должен храниться в течение всего срока службы контроллера для PickerView.

Как мне более элегантно объявить 2D-массив?

Ответы [ 6 ]

2 голосов
/ 12 апреля 2011

1: NARC

Если вы отправите +alloc, вы владеете этим объектом, и вы несете ответственность за его освобождение.Следовательно,

[[NSArray alloc] initWithObjects:ALL_SUBURBS_LABEL, @"East",@"South", @"West", @"North", nil]

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

2: Коллекции какао владеют своими элементами

Когда вы добавляете объект вКакао-коллекция, такая как NSArray, коллекции принадлежит этот объект.Он также освободит все элементы коллекции, когда они больше не будут использоваться.

3: Заключение

Ваш код без -autorelease дает вам право собственности на обасамый внешний массив и каждый внутренний массив, который является элементом самого внешнего массива.Это означает, что вы несете ответственность за освобождение этих четырех массивов (один самый внешний, три самых внутренних).Однако, поскольку самый внешний массив уже владеет самыми внутренними массивами, вам, вероятно, не нужно также владеть ими, поэтому -autorelease.

1 голос
/ 12 апреля 2011

Вы получаете право собственности, если вы выделяете массив с помощью alloc init, и поэтому вы должны освободить его, как это делается во втором коде.Вы также можете использовать: [[NSArray alloc] initWithObjects: [NSArray arayWithObjects:first,second, nil], nil];

1 голос
/ 12 апреля 2011

Ваш второй метод правильный. Дело в том, что вмещающий массив станет владельцем вложенных объектов, в то время как дополнительное право владения, полученное вами с помощью alloc, останется висящим. Немного более аккуратный подход заключается в использовании метода класса arrayWithObjects вместо alloc / initWithObjects / autorelease, но это то же самое.

0 голосов
/ 12 апреля 2011

Когда вы добавляете дочерний массив в родительский массив, родительский массив сохраняет дочерний массив.Таким образом, увеличивая количество сохранений до 2. Так как вы нигде не сохраняете ссылку на дочерний массив (массивы), счет хранения должен быть только 1, следовательно, вы должны использовать autorelease.Итак, ваша вторая версия верна.

0 голосов
/ 12 апреля 2011

Если он никогда не будет выпущен, то оба пути не будут протекать, но второй более «правильный».NSArrays не будет автоматически освобожден до тех пор, пока родительский массив не будет (никогда), поэтому все в порядке.

0 голосов
/ 12 апреля 2011

Даже если массив необходим в течение всего срока службы контроллера, вы должны освободить его с помощью метода dealloc контроллера, иначе объекты будут вытекать.

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