сохраняет ли счет приращение addSubview?

Я протестировал его, и похоже, что это так. Итак, мой вопрос: ВСЕГДА ли увеличивается счетчик удержания.

Поэтому каждый раз, когда я делаю что-то вроде этого:

UIView *theView = [[[UIView alloc] initWithFrame:(CGRect)aFrame] autorelease];
[self.view addSubview:theView];

Я на самом деле утечка памяти?

У меня есть глобальное свойство @property (nonatomic, retain) UILabel *ingredientsTextLabel;, экземпляр которого я создаю в viewDidLoad с помощью этого кода:

У меня просто есть имя свойства, в моем заголовке нет свойства для него, поэтому нет геттера и сеттера. В моем viewDidLoad:

    ingredientsTextLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, ingredientsScrollView.frame.size.width, ingredientsScrollView.frame.size.height)];
    [ingredientsTextLabel setBackgroundColor:[UIColor clearColor]];
    [ingredientsTextLabel setFont:[UIFont fontWithName:@"Helvetica" size:18]];
    [ingredientsTextLabel setText:ingredientsText];
    [ingredientsTextLabel setNumberOfLines:0];
    [ingredientsTextLabel setLineBreakMode:UILineBreakModeWordWrap];
    NSLog(@"%i",[ingredientsTextLabel retainCount]); // here retain count is 1

    CGSize maxSize = CGSizeMake(ingredientsScrollView.frame.size.width, 9999);
    CGSize ingLabSize = [ingredientsText sizeWithFont:ingredientsTextLabel.font
                                    constrainedToSize:maxSize
                                        lineBreakMode:ingredientsTextLabel.lineBreakMode];

    [ingredientsTextLabel setFrame:CGRectMake(ingredientsTextLabel.frame.origin.x, ingredientsTextLabel.frame.origin.x, ingredientsTextLabel.frame.size.width, ingLabSize.height)];
    [ingredientsScrollView addSubview:ingredientsTextLabel];
    NSLog(@"%i",[ingredientsTextLabel retainCount]); // here retain count is 2!

Теперь я подумал, что это сработает, а затем в Dealloc я могу выпустить ingredientsTextLabel, но количество сохранений равно 2, поэтому мне нужно также выпустить i после того, как я добавлюSubview? Я не понимал, что это происходит! :(


person Thomas Clayson    schedule 12.11.2010    source источник


Ответы (3)


Да, «addSubview» увеличивает количество сохранений. Это имеет смысл, потому что метод сохраняет подпредставление, которое не следует освобождать/освобождать до тех пор, пока не будет выпущено суперпредставление. Когда суперпредставление выпускается, оно также выпускает все его подпредставления.

person Felix    schedule 12.11.2010
comment
Правильный. Томас, вам не нужно делать еще один выпуск после addSubview: вы должны просто побеспокоиться о выпуске ОДИН РАЗ для каждого alloc/init. Если addSubview: увеличивает количество сохранений, его обязанность освободить. - person pablasso; 12.11.2010
comment
ага... понятно. Спасибо. Означает ли это, что если я выделяю/инициирую UIView, добавляю его как подвид self.view, а затем отпускаю его, счетчик сохранения по-прежнему равен 1? Таким образом, даже несмотря на то, что я выпустил его, могу ли я по-прежнему отправлять ему сообщения? Спасибо - person Thomas Clayson; 12.11.2010
comment
Да, это правильно. Но если вы храните ссылку на свой UIView, вы также должны сохранить этот UIView. Просто потому, что это стиль Cococa/Obj-C. - person Felix; 12.11.2010

Не используйте -retainCount.

Абсолютный счетчик удержания объекта не имеет смысла.

Вы должны вызывать release ровно столько раз, сколько раз вы заставили сохранить объект. Не меньше (если не любите утечки) и уж точно не больше (если не любите краши).

См. Руководство по управлению памятью для получения полной информации.

Если вы +new/+alloc/-retain/-copy (NARC) объекта, вам необходимо сбалансировать сохранение с выпуском (или автоматическим выпуском). Конец истории. Абсолютное количество сохранений, особенно абсолютное количество сохранений экземпляра класса, который является подклассом класса платформы, и/или переданного в код платформы, является деталью реализации и, скорее всего, не будет тем, что вы думаю должно быть.

person bbum    schedule 13.11.2010

На самом деле это так. Вы можете сослаться на это по адресу http://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/uiview/uiview.html#//apple_ref/occ/instm/UIView/addSubview:

Само собой разумеется, superView сохраняет subView в addSubview: , поэтому он освобождается при удалении subView.

person Jason Lee    schedule 21.12.2011
comment
P.S. Двоеточие в конце ссылки обязательно. - person Jason Lee; 21.12.2011
comment
+1 за ответ на вопрос, но вы написали На самом деле так и есть. Что значит? Что оно делает? Я смущен! (Отредактируйте свой ответ, используя ссылку редактирования под текстом вашего ответа). - person Shalom Craimer; 21.12.2011
comment
Ничего себе, только ответ более чем через год и немного позже, чем вопрос был задан, и действительно ответил! Scrimer Я думаю, Джейсон сказал, что на самом деле это относится к вопросу, сохраняет ли счет приращения addSubview? Не то чтобы все это стало иметь значение с появлением автоматического подсчета ссылок. :п - person Thomas Clayson; 21.12.2011
comment
Да, на самом деле это так, на вопрос, сохраняет ли счет приращение addSubview? - person Jason Lee; 22.12.2011