2011-05-25 3 views
0

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

структура моего Plist является в основном просто:

<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 выпущен, так как я никогда его не выпускаю (или мое приложение падает)?
  • Это правильный способ доступа к диктофонам и массивам из plist?
  • Я предполагаю, что initWithContentsOfFile включает в себя автореферат, но как я должен знать это? Есть ли список методов, которые включают авторекламу (или список, который этого не делает, что когда-либо будет короче)?
  • Я хотел бы иметь правило, которое действительно работает, потому что «каждый alloc или 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", если я установить его свойство сохранять в интерфейсе?

+0

Как вы реализуете/синтезируете сеттер для dict, excercises и exerciseViewContent? – cem

+0

"...'exercise' или' dict' (я устанавливаю их свойства как сохраненные в интерфейсе и синтезируя их, хотя). Обратите внимание, что 'self.dict = tempDict;' и 'dict = tempDict;' ** не ** то же самое – albertamg

ответ

4

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

dict = tempDict; 

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

Это мое управление памятью правильно, как это?

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

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

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

Это правильный способ доступа к диктофонам и массивам из plist?

Это нормально, за исключением я бы просто получить exerciseViewContent так:

exerciseViewContent = [exercises objectAtIndex:0]; 

, то вам не нужно, чтобы освободить его.

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

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

Я хотел бы иметь эмпирическое правило, что на самом деле работает, потому что «каждый Alloc или INIT нуждается в освобождении», по-видимому здесь не подходит.

Да, он подходит. Вы просто недопонимали смысл этой строки:

dict = tempDict; 
+0

Очень хороший ответ –

+0

@Praveen: У меня было много практики :) – JeremyP

+0

Lol, опыт помогает –

Смежные вопросы