Почему NSSet objectEnumerator увеличивает счетчик сохранения? - PullRequest
1 голос
/ 01 декабря 2008

После получения objectEnumerator в следующем коде счет сохранения set1 становится равным 3. Я был удивлен, увидев это, потому что не ожидал, что он изменится. Я искал документацию и не могу найти, где объясняется этот эффект.

Я предполагаю, что дополнительные сохранения, вероятно, установлены в автоматический выпуск с помощью логики перечисления Какао и не будут иметь никакого эффекта в текущем цикле событий. Логично, что логике objectEnumerator потребуется ссылка на set1, но я бы хотел знать, почему они были сделаны. Вот причина: если я предполагаю, что set1 сохранил нулевой счет после выпуска в коде, то я мог бы попытаться использовать его еще один новый набор. Не вызовет ли это проблем, поскольку set1 теперь указывает на совершенно другой объект / адрес?

Для "бонусных" баллов есть ли способ перечисления пула автоматического выпуска, чтобы увидеть, что он на самом деле содержит? ТИА

#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSValue.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSString.h>

#import <stdio.h>;

// macro to create an integer number:
#define INTOBJ(v) [NSNumber numberWithInt: v]

int main (int argc, char *argv[])
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    //Make set
    NSMutableSet *set1 = [[NSMutableSet alloc] initWithObjects:
        INTOBJ(1), INTOBJ(2), INTOBJ(5), INTOBJ(10), nil];

    printf("set1 #%lu\n", [set1 retainCount]);

    //Get enumerator of the set. This is where the retain count goes to 3:
    NSEnumerator *setEnum = [set1 objectEnumerator];
    printf("setEnum #%lu\n", [setEnum retainCount]);
    printf("set1 #%lu\n", [set1 retainCount]);

    //Iterate through the collection:
    printf("[");

    NSNumber *element;
    while ((element = [setEnum nextObject]) != nil)
        //do some this with item. printf is just for debugging:
        printf(" %i ", [element intValue]);

    printf("]\n");
    printf("set1 #%lu\n", [set1 retainCount]);

    [set1 release];
    printf("set1 after release #%lu\n", [set1 retainCount]);

    //More logic could go here reusing variable set1 since I assumed retain count = 0

    [pool release];

    return 0;
}

Ответы [ 3 ]

4 голосов
/ 01 декабря 2008

Обычно не стоит полагаться на количество объектов, так как это внутренняя деталь структуры. Вместо этого убедитесь, что ваш код соответствует принципам управления памятью, в частности, балансировка retain / new / copy и release / autorelease.

2 голосов
/ 02 декабря 2008

Предположительно, перечислитель сохраняет коллекцию, чтобы она не освобождалась во время перечисления. Перечислитель без допустимой коллекции для перечисления не будет работать очень хорошо. Фактически, для перечислителя единственный способ убедиться, что он будет работать, - это сохранить перечисляемую коллекцию.

Тем не менее, на самом деле нет никаких оснований смотреть на счет сохранения любого объекта , кроме для отладки проблемы утечки памяти / двойного выпуска. Пока вы следуете соглашениям об управлении памятью, вам никогда не придется беспокоиться о количестве сохраняемых объектов.

1 голос
/ 01 декабря 2008

Повторное использование set1 после выпуска не вызовет проблем, поскольку счет сохранения находится в объекте, на который ссылается переменная set1, а не в самой переменной.

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