Управление памятью в Objective-C - PullRequest
0 голосов
/ 16 февраля 2011

Я хочу спросить, выделил ли я переменную экземпляра для частного использования в этом классе, должен ли я немедленно опубликовать ее на сайте, или я могу зависеть от функции dealloc . (потому что, может быть, мне понадобится другая функция)?

//Player.h
@interface Player : NSObject
{
    NSMutableArray * objectArray;
}

- (void)awake;
- (void)add;

@end

//Player.m
@implementation Player : NSObject
{
    -(id) init {
        self = [super init];
        if (self !=  nil ){
            [self awake];
            [self add];
        }
        return self;
    }
    - (void) awake {
        objectArray = [[NSMutableArray alloc] init]; //is it cause leakage?
        [objectArray addObject:@"foobar"];
    }
    - (void) add {
        [objectArray addObject:@"foobar2"];
    }
    - (void) dealloc {
        [objectArray release];
        [super dealloc];
    }
}

@end

или я должен использовать свойство для установки objectArray iVar?

//Player.h
@interface Player : NSObject
{
    NSMutableArray * objectArray;
}

@property (nonatomic,retain)NSMutableArray* objectArray;

- (void)awake;
- (void)add;

@end

//Player.m
@implementation Player : NSObject
{
    -(id) init {
        self = [super init];
        if (self !=  nil ){
            [self awake];
            [self add];
        }
        return self;
    }
    - (void) awake {
        self.objectArray = [[NSMutableArray alloc] init autorelease]; //cause leakage?
        [objectArray addObject:@"foobar"];
    }
    - (void) add {
        [objectArray addObject:@"foobar2"];
    }
    - (void) dealloc {
        [objectArray release];
        [super dealloc];
    }
}

@end

если они оба не вызывают утечку, какой тип я должен использовать? я должен всегда устанавливать iVar свойство и обращаться к iVar значение с self , даже если я только хочу использовать его в этом классе?

Ответы [ 3 ]

2 голосов
/ 16 февраля 2011

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

В любом случае вам нужно будет освободить objectArray в вашем методе dealloc классов - что вы и делаете в настоящее время.

ОднакоВы должны быть осторожны с вашим методом пробуждения - если он вызывается несколько раз, то objectArray просочится.Это недостаток неиспользования свойств.Использование self.objectArray = [[NSMutableArray alloc] init] здесь освободило бы предыдущий объект.

2 голосов
/ 16 февраля 2011

По моему мнению, вы должны объявлять свойства в вашем заголовке, только если другим объектам разрешено их использовать.Нет веской причины, по которой вы бы предоставили метод -add: (как в вашем примере), который добавляет что-то в ваш массив, а также предоставляет метод получения для вашего массива, чтобы другие объекты могли манипулировать им напрямую.Это называется инкапсуляция.

Если вы хотите использовать преимущества сгенерированных методов получения / установки для файла реализации, вы всегда можете использовать продолжение класса (безымянную категорию) внутри файла реализации и включить туда объявления о свойствах.,Таким образом, вы получите реальные, автоматически сгенерированные свойства, которые видны только реализации вашего класса.

Лично я не буду использовать методы getter или setter в вашем примере.Просто выделите NSArray в вашем -init и выпустите его в -dealloc.Если ваш метод -wake может вызываться несколько раз, просто добавьте вызов [objectArray removeAllObjects], и вы обязательно получите пустой массив, не беспокоясь об управлении памятью.

1 голос
/ 16 февраля 2011

Весьма вероятно, что в первом примере будет утечка памяти, потому что вы не отправляете release в ранее установленную переменную экземпляра (если она уже существовала).

Вот почему вы должны использовать установщики свойств - они обрабатывают все эти вещи для вас.

Кроме того, поскольку вы получаете право владения переменной экземпляра через свойство (которое определяется ключевым словом retain), вы определенно утечете память, если не отправите переменную экземпляра -release сообщение в вашем -dealloc методе.

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

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