Objective-C Retain Count увеличивается с 0 до 2

Я новичок в Objective-C. Это мой первый пост здесь. Я создал синглтон для управления интерфейсом моих приложений с базой данных. Для начала я использовал NSMutableArray в качестве ivar. Как вы увидите в приведенном ниже коде и выводе журнала, счетчик сохранения равен 0 до того, как он будет назначен объекту NSMutableArray, а затем счетчик сохранения равен 2 после назначения.

Я не понимаю, почему это происходит. Это потому, что [NSMutableArray arrayWithObject:(id)] создает объект со счетчиком сохранения, равным единице, а затем присваивание self.dataList увеличивает счетчик сохранения? Безопасно ли вызывать релиз один раз? Это не похоже на правильный поступок.

Вот источник

#import <Foundation/Foundation.h>


@interface DataInterfaceObject : NSObject {
    NSMutableArray *dataList;

}

@property (nonatomic, retain) NSMutableArray *dataList;

+ (id) sharedAlloc;

@end

...

#import "DataInterface.h"

static DataInterfaceObject *sharedDataInterfaceObject = nil;

@implementation DataInterfaceObject

@synthesize dataList;

+ (id) sharedAlloc {    
    @synchronized(self) {
        if (sharedDataInterfaceObject == nil) 
            sharedDataInterfaceObject = [super alloc];
    }
    return sharedDataInterfaceObject;
}

+ (id) alloc {
    return [[self sharedAlloc] init];
}

- (id)init 
{
    @synchronized(self) {
        NSLog(@"In DataInterface init 1, RetainCount for dataList is %d", [self.dataList retainCount]);
        if (dataList == nil) {
            self = [super init];
            if (self) {
                //Instantiate list
                NSLog(@"In DataInterface init 2, RetainCount for dataList is %d", [self.dataList retainCount]);
                self.dataList = [NSMutableArray arrayWithObjects:@"Dog", @"Cat", @"Homer", @"Vanessa", @"Tour Eiffel", @"Ball", @"Lettuce", nil];
                NSLog(@"In DataInterface init 3, RetainCount for dataList is %d", [self.dataList retainCount]);
            }
        }
    }
    return self;
}

- (void)dealloc 
{
    [dataList release];
    [super dealloc];
}

@end

Журнал показывает следующее:

2011-04-06 21:18:26.931 jobs[11672:207] initislized
2011-04-06 21:18:26.933 jobs[11672:207] In DataInterface init 1, RetainCount for dataList is 0
2011-04-06 21:18:26.934 jobs[11672:207] In DataInterface init 2, RetainCount for dataList is 0
2011-04-06 21:18:26.934 jobs[11672:207] In DataInterface init 3, RetainCount for dataList is 2

person Jim    schedule 07.04.2011    source источник
comment
Вы пробовали заявление о выпуске, чтобы увидеть, что происходит?   -  person Flipper    schedule 07.04.2011
comment
Эй, это еще один вопрос для @bbum. Вероятно, у него уже есть готовый ответ.   -  person    schedule 07.04.2011
comment
К счастью, сообщество относительно новых людей позаботилось об этом! Мне больше не нужно кричать. :) stackoverflow.com/questions/3730804/ stackoverflow.com/questions/4636146/when-to-use-retaincount   -  person bbum    schedule 07.04.2011


Ответы (3)


Код:

[NSMutableArray arrayWithObjects:@"Dog", @"Cat", @"Homer", @"Vanessa",
    @"Tour Eiffel", @"Ball", @"Lettuce", nil];

Создает автоматически освобождаемую переменную с числом сохранений, равным 1, которая будет выпущена когда-нибудь в будущем. Ваше свойство также вызывает функцию сохранения, поэтому при вызове инструкции печати объект будет иметь счетчик сохранения, равный 2, а затем вскоре уменьшится до 1.

person skorulis    schedule 07.04.2011
comment
Где «скоро» означает всякий раз, когда соответствующий пул автоматического освобождения опорожняется, обычно (но не обязательно) при повторении цикла выполнения. - person ; 07.04.2011
comment
Лучше всего думать об удержании исключительно как о дельтах, а не как об абсолютных числах. Кстати; в приведенном выше примере все эти строковые объекты имеют абсолютно [бесполезный] счетчик сохранения ~ 2147483647 - person bbum; 07.04.2011

Не используйте счетчики сохранения для отладки, вы сойдете с ума. Если у вас возникли проблемы с утечкой памяти или избыточным освобождением, убедитесь, что вы соблюдаете правила управления памятью.

Основные компетенции Cocoa

В Cocoa With Love есть хорошая статья о создании синглетонов в Cocoa.

person Terry Wilcox    schedule 07.04.2011

Да, причина сразу в два заключается в том, что а) вы создаете объект и б) вы сохраняете объект, назначая его self.dataList. Однако вы не несете ответственности за создание объекта, так как вы не вызывали +alloc, поэтому ваш -dealloc может освободить dataList только один раз.

Тем не менее, @Terry Wilcox прав: не смотрите на -retainCount.

person Caleb    schedule 07.04.2011