Отправлено на освобожденный экземпляр
Всякий раз, когда я нажимаю контроллер вида на свой стек, а затем выталкиваю его, я получаю эту ошибку:
*** -[CALayer retainCount]: message sent to deallocated instance <memory address>
Кажется, что это происходит сразу после вызова dealloc
на контроллер вида, который выгружается и является эксклюзивным только для этого контроллера вида. Я уверен, что CALayer имеет какое-то отношение к самому представлению, поскольку я их не использую.
Любые идеи?
Изменить:
Вот обратная линия
(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)
Ответы
Ответ 1
У меня была аналогичная проблема; Оказывается, я не сохранял UIButton правильно. Как я нашел причину:
- Включить зомби
- Запустить проект с помощью инструмента "Распределения"
- Используйте приложение, чтобы вызвать ошибку
- Убедитесь, что на экране отображаются сообщение "Zombie Messaged" на временной шкале
- Должна быть ссылка, которая открывает детали CALayer: когда она была выделена и освобождена
- Вас интересует место, где было выделено, должно быть, что ага!!! место в вашем коде
Удачи!
Ответ 2
Это немного сложно, мой был двойной версией в функции dealloc одного из классов (m/xib), который у меня был в виде таблицы как стиль строки. Инструменты ничего не показывали об объекте, но проверка стоп-кода была действительно полезной, чтобы определить, какой класс был для -1.
![Sample]()
Ответ 3
У меня была аналогичная проблема. Моя проблема заключалась в том, что одна из переменных объекта, объявленных в интерфейсе, была ошибочно объявлена с помощью (nonatomic, assign)
, а не как (nonatomic, retain)
, как и должно было быть. Это привело к отправке сообщения о выпуске на объект, который уже имеет значение 0 (= crash).
Ответ 4
У меня была такая же ошибка, и это было потому, что я создал UIButton с помощью buttonWithType
(например, [UIButton buttonWithType:UIButtonTypeRoundedRect]
) и выпустил это потом. Это было неправильно, потому что buttonWithType
уже включен autorelease
. Поэтому я удалил release
, и ошибка исчезла.
Ответ 5
Отслеживание того, какой вид действительно полезен! Это может быть довольно тривиально, если вы знаете фрейм и какие суперслои и подслои связаны с этим представлением... Если вы регистрируете все слои, это просто поиск и поиск того же адреса памяти. Удачи!:)
Добавить эту категорию в ваше приложение
Category-заголовок:
#import "CALayer+debug.h"
@interface CALayer (Debug)
-(NSString*)debugDescription;
-(NSString*)debugLayerTree;
@end
Category-Реализация:
#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];
Ответ 6
У меня есть подозрительное подозрение, что это связано с пулом автоматического выпуска...
Ответ 7
Я получал ту же ошибку. Я создал объект UIView
, чтобы удерживать две кнопки, которые я затем добавил в свой пункт навигации rightBarButtonItem
. Проблема в том, что я использовал метод factory buttonWithType
для создания кнопок, но я просто alloc
и initWithFrame
мой просмотр. Затем, после того, как я закончил просмотр, я выпустил его, а позже, когда система пыталась выпустить две кнопки (subviews уже выпущенного UIView
) - crash - он отправил сообщение уже выпущенным кнопкам, Надеюсь, что это поможет кому-то сэкономить время на подобных неприятностях.