Что выпустить - PullRequest
       17

Что выпустить

0 голосов
/ 25 мая 2011

У меня проблема с пониманием управления памятью, хотя я думал, что понял.После того, как я импортировал свои данные из списка, я полностью запутался в своем понимании подсчета ссылок (и потратил целый день, пытаясь это исправить)

Структура моего списка в основном просто:

<dict>
<key>Menue1</key>
<array>
    <dict>
        <key>pic1</key>
        <string>a</string>
        ...and so on...
    </dict>
    <dict>
        <key>pic1</key>
        <string>a</string>
        ...and so on...
    </dict>
    <dict>
        <key>pic1</key>
        <string>a</string>
        ...and so on...
    </dict>
</array>
<key>Menue2</key>
<array>
    <dict>
        <key>pic1</key>
        <string>a</string>
        ...and so on...
    </dict>
    <dict>
        <key>pic</key>
        <string></string>
        <key>text</key>
        <string></string>
    </dict>
</array>
</dict>

И в коде я получаю доступ к этому контенту через

//to get the path
path = [[NSBundle mainBundle] pathForResource:@"plistsName" ofType:@"plist"]; 

//to get the root dictionary from path      
NSDictionary *tempdict = [[NSDictionary alloc] initWithContentsOfFile:path]; 
    dict = tempdict;
// [tempdict release]; <-- app crashes when I release this

// to get the Array of dicts inside of the dict "Menue1"
exercises = [dict objectForKey:@"Menue1"]; 

// to get the dictionary containing the detailed informations
exerciseViewContent = [[NSDictionary alloc] initWithDictionary:[exercises objectAtIndex:0]];

Я понимаю идею подсчета ссылок (я так думаю), но я явно проваливаю базовую математику.

Из-за @interface Я полагаю, что ссылки были следующими:

dict = 1
exercises = 1
exerciseViewContent = 1

После viewDidLoad, где я делаю все эти вещи выше, я предполагаю, что это похоже на

dict = 1
exercises = 1
exerciseViewContent = 2
tempdict = 1

Итак, во-первых, я подумал, что мне придется выпустить exerciseViewContent один раз внутри viewDidLoad, а также tempdict и выпустить все три (dict, exercise, exerciseViewContent) в deallocчтобы получить их все равными 0. После долгого времени я обнаружил, что я должен выпустить exerciseViewContent в dealloc, но не exercise или dict (я устанавливаю их свойства как сохраненные в интерфейсеи синтезировать их, хотя), но не нужно выпускать tempdict полностью - это больше, чем я понимаю, поскольку я определенно использовал alloc с ним.Просто поигрывая, он работает сейчас (до сих пор).

Итак, я хотел бы знать:

  • Прежде всего: правильно ли работает мое управление памятью?
  • Когда, например, dict выпущен, так как я никогда не выпускаю его (или мое приложение падает)?
  • Является ли это правильным способом доступа к диктам и массивам из списков?
  • Я предполагаю, что initWithContentsOfFile включает авто-релиз, но откуда мне это знать?Есть ли список методов, которые включают авто-релиз (или список, который не делает, что когда-либо будет короче)?
  • Я бы хотел иметь практическое правило, которое действительно работает, потому что «каждыйили init нуждается в выпуске "очевидно, здесь не подходит.

Далее, мне нужно освободить" путь "?

А также:

[timer invalidate];
timer = nil;

то же самое, что и выпуск, поскольку мне, видимо, также не нужно выпускать таймер (NSTimer), хотя я установил его свойство для сохранения?Или это потому, что NSTimer не нужно выпускать, как и NSInteger?И где в ссылке на класс я могу увидеть, какой тип должен быть освобожден, а какой нет по умолчанию?

И:

  • (из шаблона Xcode :)

    (void)viewDidUnload {
        [super viewDidUnload];
        // Release any retained subviews of the main view.
        // e.g. self.myOutlet = nil;
    }
    

Придется ли мне выпускать "myOutlet", если я установлю его свойство для сохранения в интерфейсе?

1 Ответ

4 голосов
/ 25 мая 2011

Переменные dict и tempDict являются указателями на объекты, а не на сами объекты. Поэтому, когда вы делаете это:

dict = tempDict;

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

Правильно ли работает мое управление памятью?

Без [tempDict release], вплоть до точки да. Когда вы закончите с ними, вам нужно освободить и dict, и exercViewContent, потому что вы получили их с помощью alloc.

Когда, например, выпущен dict, так как я никогда не выпускаю его (или мое приложение вылетает)?

Как я уже говорил выше, tempDict указывает на тот же объект. Отпустите tempDict, и вы отпустите dict.

Является ли это правильным способом доступа к диктантам и массивам из списков?

Все в порядке, за исключением того, что я просто получаю упражнениеViewViewContent следующим образом:

exerciseViewContent = [exercises objectAtIndex:0];

тогда вам не нужно выпускать его.

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

Нет, это не так. Важным моментом является то, что объект был получен с помощью alloc, что означает, что он принадлежит вам. Как вы должны это знать, понимая правила управления памятью C ocoa .

Я бы хотел иметь практическое правило, которое действительно работает, потому что "каждый alloc или init нуждается в выпуске", очевидно, здесь не подходит.

Да, это подходит. Вы просто неправильно поняли значение строки:

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