Във връзка с въпроса тук.
Решенията, предоставени в тази тема, включват:
- Ако сте умни къде и колко променливи декларирате, това ще отиде в стека.
- Деактивирайте Guard Malloc, ако е необходимо.
Освен това като цяло: 3. Уверете се, че освобождавате променлива, за която всъщност сте заделили памет!!
Нямам нито един от горните проблеми. Има много малко разпределени в стека променливи, които използвам във функциите, да речем 2-3 във всяка. Но тъй като функциите се извикват в цикъл няколко пъти, изглежда, че задейства изключение.
И тук е кикърът, това не се случва само за статично разпределени променливи, но и за неща в купчината! Получавам грешки в страницата на автоматично освободени декларации на променливи NSNumber, които използвам няколко вътре в цикъла, както и речник, който разумно разпределям и освобождавам в рамките на обхвата на функцията, всеки път, когато се извиква.
И така, защо се случва това и защо, по дяволите, променливите на купчината се засягат? Изобщо не разбирам, моля, хвърлете малко светлина върху това. :)
Аз съм на IOS5 с XCode 4.2, iPhone/iPad симулатор.
Благодаря!
Поздрави, Dev
Редактиране: Примерен код
- (void)doSomething {
NSInteger fun = 3;
NSInteger time = 4;
NSInteger overload = fun*time;
NSString *string = [NSString stringWithFormat:@"%d",overload];
NSObject *myCustomObject = [[NSObject alloc] init];
[myCustomDictionary setObject:myCustomObject forKey:string];
[myCustomObject release];
//myCustomDictionary is an iVar, alloced in the class's init method, and released in dealloc and not touched anywhere in between
}
//doSomething gets called several times through the course of execution as the state of the view changes, the user interacts with it etc, often 2-3 times during one state change.
Кодът нарочно е неясен, но в същото време е ТОЧНО толкова прост, колкото в примера. Както и останалата част от кода в целия проект. Няколко функции, всяка от които върши малко работа, толкова добре самостоятелни по отношение на паметта, колкото тази.
Преди се сблъсках с проблеми с EXC_BAD_ACCESS и в този момент се позовах на този въпрос. В моя случай обаче не създавах множество променливи в стека в рамките на цикъл, те се създаваха многократно от функция, която се извиква няколко пъти в хода на изпълнението. В идеалния случай променливите трябва току-що да са унищожени в края на функционалния обхват. Не знам защо това не се случи.
Както и да е, за да разреша това и да предотвратя случването на множество разпределения, накрая декларирах моите разпределени в стека променливи като всички static
. Това е лоша практика, но точно това трябваше да направя, за да проработи. И работеше, докато не се сблъсках ОТНОВО с проблема с функцията "doSomething".
Така че трудността в "doSomething" беше, че не създавах само разпределени в стека променливи, но и куп неща. Така че първо започнах да получавам EXC_BAD_ACCESS на променливите NSInteger, след което се опитах да го поправя отново, като ги декларирах като статични. Проработи, но сега EXC_BAD_ACCESS започна да се появява на автоматично освободената променлива и накрая на персонализираната променлива - това беше моментът, в който се затрудних. Спазвам всички правила за управление на паметта и имам променливи на стека и купчината, които се блъскат навсякъде по мен. Ако беше само купчина неща или стек неща вътре в цикъл, можех да разбера, че има грешка НЯКЪДЕ. Но тук не е нито едното, нито другото, това са съвършено невинни променливи, които се разпределят в стека вътре в ЕДНА функция, която НЕ се извиква в цикъл, и обикновени автоматично освобождавани променливи, които никога не се запазват или освобождават, хвърлени към тях от друго място в кода. Това, което прави всичко още по-лошо, е, че точките на отказ са произволни - не само в тази функция, но практически всяка, която се извиква няколко пъти в хода на изпълнение на проекта.
Edit2: Оказва се, че в този случай вината е моя. Вижте моя отговор за подробности. Съжалявам, че губя времето на хората. :\