Проблема обнаружения утечек в iOS с xCode 4.3

У меня очень странная проблема с инструментами утечки памяти xCode 4.3... В основном это не работает в следующем случае...

  1. Проект создан без поддержки ARC.
  2. Создайте простой класс, который наследует UIView
  3. используйте «кнопку», чтобы создать экземпляр этого класса и «слить» его... утечка не будет обнаружена Leak Instruments

так вот код ПРОБЛЕМАТИЧЕСКОГО класса

@interface LeakTestView :  UIView
- (id)initWithFrame:(CGRect)frame;
@end

@implementation LeakTestView
- (id)initWithFrame:(CGRect)frame
{
    NSLog(@"initWithFrame called");
    self = [super initWithFrame:frame];
    if (self) {

        // Initialization code
    }
    return self;
}
@end

И теперь я создаю утечку ...

- (IBAction)leak:(id)sender {
    LeakTestView* leak=[[LeakTestView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
    NSLog(@"class is %@", [leak class]);
}

Так что проблема в том, что эта утечка не будет обнаружена...

Если я изменю базовый класс на NSObject и вместо initWithFrame переопределю init (см. ниже), то утечка будет обнаружена....

Итак, вот код утечки, которая БУДЕТ обнаружена

@interface LeakTestView : NSObject
- (id) init;
@end


@implementation LeakTestView

- (id) init {
    NSLog(@"init called");
    self = [super init];
    if (self) {

    }
    return self;
}
@end

Если я сейчас создам объект и оставлю его - сработает обнаружение утечки, и утечка будет "увидена" в Инструменты.

- (IBAction)leak:(id)sender {
    LeakTestView* leak=[[LeakTestView alloc]init];
    NSLog(@"class is %@", [leak class]);
}

Есть идеи, что происходит? Почему утечка подкласса UIView не будет обнаружена, но изменение базового класса на NSObject «устранит» проблему? Да, и да, утечку объекта можно увидеть с помощью «Отметить кучу» — одна отметка перед утечкой и одна отметка после того, как я нажму кнопку и создам утечку — класс будет виден в дельте кучи...

РЕДАКТИРОВАТЬ: еще одна "забавная" ситуация... Если я удалю "инициализацию" (только выделение объекта)

LeakTestView* leak=[LeakTestView alloc];

тогда утечка будет обнаружена независимо от базового класса... Что, черт возьми, здесь происходит?

EDIT2: еще одна "забавная" вещь. Проблема обнаружения утечки наблюдается только в Симуляторе (iOS 5.0, 9A334 у меня), но утечка будет обнаружена всегда при использовании устройства iPad...

Любые комментарии? Если у вас нет проблемы или вы считаете, что я говорю «ложь», просто скажите мне, что я ошибаюсь, и описанный выше случай работает «просто отлично» - утечки, которые я описываю, обнаруживаются вашими инструментами xCode!


person Sunman    schedule 27.02.2012    source источник
comment
Какие инструменты?? Какие течеискатели вы используете?   -  person Hot Licks    schedule 01.02.2013


Ответы (1)


Может не течет?

Вы вызываете метод, который является черным ящиком. Как реализован UIView initWithFrame, не ваше дело. У него есть своего рода контракт, но вы не имеете права требовать его утечки больше, чем вы можете предположить, что счетчик удержания равен 1.

Утечки — полезный инструмент, но он не делает того, что вы думаете. Он не говорит вам, когда вы облажались. Он сообщает вам, когда у вас есть недоступные распределения. Это не одно и то же.

Или это может быть ошибка.

person hooleyhoop    schedule 28.02.2012
comment
Спасибо за ответ. Я знаю, что Leaks обнаруживает недостижимые выделения (и этот инструмент не является волшебным решением, чтобы показать, где проблемы в коде), но если я проверю количество удержаний утекшего объекта, он покажет 1 (как и должно быть), поэтому единственное сохранение который активен из alloc. Так что для меня есть утечка, которую Инструмент не может найти даже такой простой. Очень легко создать пример проекта, чтобы протестировать его самостоятельно - просто используйте симулятор и слейте подкласс UIView, и проверьте, найдут ли его инструменты... - person Sunman; 28.02.2012
comment
Я знаю, я полностью согласен, что это странно, но количество сохранений на самом деле ни о чем вам не говорит. Игнорировать › friday.com/bbum/2011/12/ 18/retaincount-is-useless - person hooleyhoop; 28.02.2012
comment
Я знаю, что счетчик сохранения нельзя использовать, чтобы сказать, сколько внешних объектов ссылаются на меня из-за реализации @property и других факторов, но в некоторых случаях он дает информацию о том, что происходит, и в приведенном выше случае он гарантирует, что единственная ссылка к вновь созданному объекту из alloc, а initWithFrame не увеличивает счетчик сохранения и, таким образом, предотвращает обнаружение утечки инструментом Leaks... - person Sunman; 28.02.2012