Почему сохранить счет больше, чем я ожидаю (используя addSubview) - PullRequest
0 голосов
/ 26 июля 2010

Почему переменная счетчика равна 3, а не 2?

@interface ScoreView : UIImageView
...


- (id)initWithFrame:(CGRect)frame 
{   
    if (!(self = [super initWithFrame:frame])) 
        return self;

    _scoreLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,0, 10, 10)];
    [self addSubview:_scoreLabel];

    int counter = [[[self subviews] objectAtIndex:0] retainCount]; // WHY 3?
    return self;
}

Ответы [ 3 ]

3 голосов
/ 26 июля 2010

-retainCount не является надежным .

Важно: Этот метод обычно не имеет значения при отладке проблем управления памятью.Поскольку любое количество объектов каркаса могло сохранить объект для хранения ссылок на него, в то время как пулы автоматического выпуска могут содержать любое количество отложенных выпусков для объекта, маловероятно, что вы можете получить полезную информацию из этогоmethod.

В вашем случае особая причина в том, что -subview также приводит к тому, что все подпредставления сохраняются один раз, путем копирования значения .layer.sublayers в новый массив*:

UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
NSLog(@"%d", [label retainCount]);  // 1
[someView addSubview:label];
NSLog(@"%d", [label retainCount]);  // 2
[someView subviews];
NSLog(@"%d", [label retainCount]);  // 3

Не нужно беспокоиться об этом, так как массив автоматически освобождается, а retainCount позже возвращается к 2.Все, что вам нужно, это убедиться, что причина подсчета чистого удержания текущей функцией соответствует статусу владения.


*: Конкретная реализация .subviews:

-(NSArray*)subviews {
            // irrelevant ... snipped

        NSArray* sublayers = [_layer.sublayers copy];
        int count = [sublayers count];

            // irrelevant ... snipped

            res = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks);
            for (int i = 0; i < count; ++ i) {
                UIView* view = _UIView([sublayers objectAtIndex:i]);
                if (view)
                    CFArrayAppendValue(res, view);
                    // ^-- this causes an extra -retain to each subview.
            }

            // irrelevant ... snipped
 }
1 голос
/ 26 июля 2010

Убедитесь, что закрывающие скобки ']' при отправке сообщения -

  _scoreLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,0, 10, 10)];//here
  [self addSubview:_scoreLabel];

  int counter = [[[self subviews] objectAtIndex:0] retainCount]; //here

, теперь проверьте и дайте нам знать о дальнейшей проблеме.

0 голосов
/ 26 июля 2010

Я думаю, что вы не знаете о механизме удержания.

Это очень просто.

методы инициализатора [init] и [copy] должны увеличить retainCount. ==> retainCount == 1 после вызова [addSubview] self получает новое сохранение _scoreLabel, затем retainCount + 1 ==> retainCount == 2

Итак, вы получили retainCount (2)

U должен изменить ваш код следующим образом.

_scoreLabel = [[UILabel alloc] initWithFrame: CGRectMake (0,0, 10, 10);

==> _scoreLabel = [[[UILabel alloc] initWithFrame: CGRectMake (0,0, 10, 10)] autorelease];

или показать выпуск вызова как этот

==> [_scoreLabel release];

Методы [autorelease] освобождают экземпляр после завершения обработки события. Вы должны вызвать [autorelease] или [release] после инициализации экземпляра вызовом [init] или [copy].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...