отправлено в освобожденный экземпляр - PullRequest
18 голосов
/ 04 марта 2010

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

*** -[CALayer retainCount]: message sent to deallocated instance <memory address>

Похоже, это происходит сразу после вызова dealloc на контроллере представления, который отключен и является эксклюзивным только для этого контроллера представления. Я уверен, что CALayer как-то связан с самим представлением, поскольку я ими не пользуюсь.

Есть идеи?

Edit: Вот обратный след

(gdb) bt
#0  0x01fcd3a7 in ___forwarding___ ()
#1  0x01fa96c2 in __forwarding_prep_0___ ()
#2  0x01fc10e8 in CFGetRetainCount ()
#3  0x01cbc770 in CA::release_root_if_unused ()
#4  0x01cbc707 in x_hash_table_remove_if ()
#5  0x01cbc4ec in CA::Transaction::commit ()
#6  0x01cc4838 in CA::Transaction::observer_callback ()
#7  0x01fa5252 in __CFRunLoopDoObservers ()
#8  0x01fa465f in CFRunLoopRunSpecific ()
#9  0x01fa3c48 in CFRunLoopRunInMode ()
#10 0x027dd615 in GSEventRunModal ()
#11 0x027dd6da in GSEventRun ()
#12 0x0057cfaf in UIApplicationMain ()
#13 0x00002dec in main (argc=1, argv=0xbfffeed0) 

Ответы [ 7 ]

12 голосов
/ 29 сентября 2010

У меня была похожая проблема; Оказывается, я не сохранил UIButton должным образом. Как я нашел причину: - Включить зомби - Запустите проект с помощью инструмента «Распределения» - Используйте приложение, чтобы вызвать ошибку - Убедитесь, что инструменты показывают сообщение «Zombie Messaged» на временной шкале - Там должна быть ссылка, которая открывает детали CALayer: когда он был выделен и освобожден - Тебя интересует место, где находится, должно быть, что ага !!! место в вашем коде

Удачи!

7 голосов
/ 02 марта 2011

Это немного сложно, у меня был двойной релиз в функции dealloc одного из классов (m / xib), который у меня был в виде таблицы как стиль строки. Инструменты не показывали много об объекте, но проверка callstack была действительно полезной, чтобы точно определить, какой класс был к -1.

Sample

4 голосов
/ 16 ноября 2010

У меня была похожая проблема. Моя проблема заключалась в том, что одна из объектных переменных, объявленных в интерфейсе, была ошибочно объявлена ​​с (nonatomic, assign), а не с (nonatomic, retain), как это должно было быть. Это привело к тому, что сообщение об освобождении было отправлено объекту с уже сохраненным счетчиком 0 (= сбой).

3 голосов
/ 04 мая 2011

У меня была та же ошибка, и это потому, что я создал UIButton с помощью buttonWithType (например, [UIButton buttonWithType:UIButtonTypeRoundedRect]) и впоследствии выпустил ее. Это было неправильно, потому что buttonWithType уже включил autorelease. Поэтому я удалил свой release, и ошибка исчезла.

1 голос
/ 28 ноября 2011

Отслеживание, какое представление действительно полезно! Это может быть довольно тривиально, если вы знаете фрейм и какие суперслои и подслои связаны с этим представлением ... Если вы регистрируете все слои, то просто ищите и находите один и тот же адрес памяти. Удачи! :)

Добавить эту категорию в ваше приложение

Категория-Header:

#import "CALayer+debug.h"

@interface CALayer (Debug)

-(NSString*)debugDescription;
-(NSString*)debugLayerTree;

@end

Категория-Реализация:

#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
#import "CALayer+debug.h"
#import <UIKit/UIKit.h>
#import <objc/runtime.h> 
#import <objc/message.h>


@implementation CALayer (Debug)

//....

void Swizzle(Class c, SEL orig, SEL new)
{
    Method origMethod = class_getInstanceMethod(c, orig);
    Method newMethod = class_getInstanceMethod(c, new);
    if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
        class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
    else
        method_exchangeImplementations(origMethod, newMethod);
}

+ (void)swizzle {
    Swizzle([self class], @selector(init), @selector(newInit));
}

- (id)newInit {
    self = [self newInit];

    [self performSelector:@selector(log) withObject:self afterDelay:0.5];

    return self; // calls old method
} 

- (void)log { 
    NSLog(@"%@", [self debugDescription]);
}

- (NSString *)debugDescription {
    return [NSString stringWithFormat:@"%@ frame=%@ zAnchor=%1.1f, superlayer: %@>", [self description], NSStringFromCGRect(self.frame), self.zPosition, self.superlayer];
}


@end

Звонок, например, с AppDelegate

[CALayer swizzle];
0 голосов
/ 07 ноября 2011

Я получаю ту же ошибку. Я создал объект UIView для двух кнопок, которые затем добавил к элементу навигации rightBarButtonItem. Проблема в том, что я использовал фабричный метод buttonWithType для создания кнопок, но я просто alloc и initWithFrame мой взгляд. Затем, после того, как я закончил просмотр, я отпустил его, а позже, когда система пыталась отпустить две кнопки (подпредставления уже выпущенного UIView) - сбой - он отправлял сообщение уже выпущенным кнопкам , Надеюсь, это поможет кому-то сэкономить время на подобных неприятностях.

0 голосов
/ 04 марта 2010

У меня есть подозрение, что это связано с пулом автоматического выпуска ...

...