Пожалуйста, объясните мне об этой утечке

#uiview #beginanimations

#uiview #beginanimations

Вопрос:

В моем журнале появилось следующее сообщение об ошибке:

 2011-10-13 10:41:44.504 Provision[386:6003] *** __NSAutoreleaseNoPool(): Object 0x4e0ef40 of class CABasicAnimation autoreleased with no pool in place - just leaking
2011-10-13 10:41:44.505 Provision[386:6003] *** __NSAutoreleaseNoPool(): Object 0x4b03700 of class NSConcreteValue autoreleased with no pool in place - just leaking
2011-10-13 10:41:44.506 Provision[386:6003] *** __NSAutoreleaseNoPool(): Object 0x4b04840 of class __NSCFDictionary autoreleased with no pool in place - just leaking
  

При запуске следующего кода появляется сообщение об ошибке.

 CGRect newFrame = [viewTop frame];
newFrame.origin.x = 0;
newFrame.origin.y = 0;
[UIView beginAnimations:@"nil1" context:nil];
[UIView setAnimationDuration:0.3f];
[viewTop setFrame:newFrame];
[UIView commitAnimations];
  

Есть понимание? Спасибо за вашу доброту

Ответ №1:

Это происходит потому, что вы используете автоматически выпущенные объекты, когда нет пула автоматического выпуска. Вы можете прочитать больше о NSAutoreleasePool здесь .

В вашей разработке cocoa вы, возможно, видели подобные выражения:

 @"string text"
[NSMutableArray arrayWithCapacity: 42]
[someObject autorelease]
  

Все они используют пул авторелиза. В первых двух случаях autorelease объектам отправляется сообщение для вас. В последнем случае мы отправляем его объекту явно. В autorelease сообщении говорится: «уменьшите количество ссылок, когда ближайший пул авторелиза будет исчерпан». Вот пример:

 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSObject *myObject = [[NSObject alloc] init]; // some object
[myObject autorelease]; // send autorelease message
[pool release]; // myArray is released here!
  

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

Обычно в программировании Cocoa NSAutoreleasePool всегда доступен an . Цикл NSApplication выполнения истощает его на каждой итерации. Однако, если вы выполняете работу вне основного потока (т. Е., Если Вы создали свой собственный поток) или если вы выполняете работу перед вызовом NSApplicationMain или [NSApp run] , пула авторелиза не будет. Обычно вы можете исправить это, добавив один:

 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
CGRect newFrame = [viewTop frame];
newFrame.origin.x = 0;
newFrame.origin.y = 0;
[UIView beginAnimations:@"nil1" context:nil];
[UIView setAnimationDuration:0.3f];
[viewTop setFrame:newFrame];
[UIView commitAnimations];
[pool release];