Методы из @synthesize? - PullRequest
       1

Методы из @synthesize?

0 голосов
/ 18 февраля 2010

Когда вы синтезируете свойство (см. Ниже)

@interface CelestialBody : NSObject {
    NSString *name;
}
...

@interface Planet : NSObject {
    NSString *name;
    int mass;
    CelestialBody *moon;
}
@property(nonatomic, retain) NSString *name;
@property(assign) int *mass;
@property(nonatomic, retain) CelestialBody *moon;
...

@implementation Planet
@synthesize name;
@synthesize mass;
@synthesize moon;
...

Вы получаете сеттеры и геттеры для каждого из iVars (то есть)

[newPlanet setName:@"Jupiter"];
[newPlanet setMass:57];
NSString *closestName = [newPlanet name];
int largestMass = [newPlanet mass];

CelestialBody *newMoon = [[CelestialBody alloc] initWithName:@"Callisto"];
[self setMoon:newMoon];
[newMoon release];

, но вы также получаете возможностьотпустите объект, используя ...

// Releases the object (frees memory) and sets the object pointer to nil.
[self setMoon: nil];

Разумеется, для каждого класса будут делок.

// Moon
-(void)dealloc {
    [name release];
    [super dealloc];
}

// Planet
-(void)dealloc {
    [name release];
    [moon release];
    [super dealloc];
}

Я правильно понял?

Гари

Ответы [ 4 ]

2 голосов
/ 18 февраля 2010

Если ваш объект планеты не объявлен как свойство в каком-либо другом классе, используя атрибуты retain / copy, вы не можете освободить его таким образом.

Когда вы объявляете свойство с помощью функции сохранения / копирования, результирующий установщик высвобождает старое значение и присваивает новое значение, сохраняя или копируя его в процессе. Если вы передадите nil, вы освободите старое значение и присвоите nil, сохранив или скопировав его, а оставив / скопировав nil - это nil, так что в итоге вы освободите старое значение и назначите nil для ivar.

Это приемлемый способ освобождения переменных экземпляра.

Чтобы выпустить экземпляр newPlanet таким способом, вам нужно было бы объявить его в классе как свойство с сохранением или копированием.

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

Или в методе dealloc класса Planet вы можете сделать:

self.name = nil;

Это освободит имя и присвоит ему ноль.

1 голос
/ 19 февраля 2010

«Вы также получаете возможность освободить объект»

Да, если вы не объявили это с атрибутом assign.

Как вы, вероятно, знаете, одна из причин (хотя, возможно, и не основная) использования объявленных свойств заключается в том, что вы можете сделать:

self.moon = aMoon;

вместо;

[self setMoon:aMoon];

Они эквивалентны. Это означает, что ваше освобождение может выглядеть так:

self.moon = nil;  // Releases and sets to nil

Но не забывайте никогда не делать:

moon = nil; // Sets to nil, doesn't release

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

0 голосов
/ 18 февраля 2010

Я думаю, вы не правильно поняли. После обновления вашего вопроса, да, вы можете сделать это, а также:

self.moon = [[CelestialBody alloc] initWithName:@"Callisto"];

и выпустите его позже, вероятно, в вашем методе dealloc:

self.moon = nil;

Документация по свойствам Apple Objective-c 2.0 и управлению памятью довольно хорошая. Проверьте библиотеку Mac Dev Center.

0 голосов
/ 18 февраля 2010

Ваш пример показывает синтез иваров одного класса (тех, что на Планете), но использование другого (каким бы ни было "я"). Является ли свойство newPlanet для self в вашем последнем примере также синтезированным как (retain)? Если так, то: Да, если установить для newPlanet значение nil, то будет выпущена новая версия «newPlanet» самого себя.

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