ивары и как правильно реализовать их значения (iPhone) - PullRequest
1 голос
/ 01 марта 2010

Я некоторое время разрабатывал приложение, и теперь я попал в раздел "Инструменты-утечки".

Я помню одну вещь, которая озадачивала меня в отношении иваров несколько месяцев назад, когда я учился. Я немного поверил в это и просто следовал тому, как это делали Apple и другие. Насколько я могу прочитать, средства доступа, созданные SDK, позаботятся об управлении памятью.

Но как сами ивары инициализируются?

Если у меня есть такой ивар в моем интерфейсе;

@interface
    {   
    NSArray *results;
    }

    @property(nonatomic, retain) NSArray *results;
    @end

@implementation
@synthesize results;

Если я во время выполнения попытаюсь сделать это:

[self setResults:allReadyInitializedArray];

Это приведет к сбою, сообщая, что этот объект результата не был инициализирован. Однако если я сделаю это:

self.results = [[NSArray alloc] init]; //Im assigning this property memory, but hasn't the SDK already done that?
[self setResults:allReadyInitializedArray];

это будет работать, но, видимо, утечка памяти.

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

Имеет ли это какое-то отношение к ивару, имеющему тип NSArray / NSMutableArray, я не могу вспомнить, что это была проблема с другими иварами.

Проблема была особенно заметна в моем анализаторе XML, где мне постоянно нужно устанавливать значение ivar, использовать его, перезаписывать это значение, использовать новое значение и т. Д.

Кто-нибудь, пожалуйста, помогите мне обрисовать в общих чертах правильный путь "перехода от": @property () -> @synthesize -> использование ivar -> для освобождения?

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

Ответы [ 2 ]

2 голосов
/ 01 марта 2010

Все ивары изначально установлены в ноль, поэтому вам нужно создать их экземпляр перед использованием. Трудно сказать, почему setResults может выдавать ошибки, не видя его реализации.

self.results = [[NSArray alloc] init];

Здесь вы создаете новый объект массива с использованием метода alloc - его счетчик сохранения равен 1. После этого ваш метод setter сохраняет ваш массив еще раз, и поэтому ваши первые объекты остаются «необработанными», что приводит к утечке памяти. Чтобы устранить утечку, вы можете переписать свой код как:

self.results = [[[NSArray alloc] init] autorelease];
// or
self.results = [NSArray arrayWith...]; // any NSArray's convenience method that returns autoreleased object.  
0 голосов
/ 01 марта 2010

Насколько я понимаю,

self.results = anArray;

совпадает с

[self setResults:anArray];

только потому, что в этом случае свойство является свойством.

Способ реализации setResults: устанавливается параметром @property (в этом случае он сохранит новое значение). Таким образом, это означает, что anArray будет иметь счет сохранения 1. После установки self.results, anArray будет иметь счет сохранения 2. Вот почему вы хотите освободить ранее использованный массив anArray. Тем не менее, я не понимаю, почему setResults: вылетает при настройке. (Может быть, он просто падает, только когда вы пытаетесь использовать self.results, вместо того, чтобы устанавливать его?) Я сам только начинающий, если что-то не так, я настоятельно рекомендую всем, кто читает это, сообщать мне, что не так или правильно. Все еще учусь этому сам.

Как Apple это сделает:

В файле .h

@property (nonatomic, retain) NSArray *results

В файле .m

@synthesize results;

- (id)init {
    NSArray *anArray = [[NSArray alloc] init];    // retainCount = 1
    self.results = anArray;                       // retainCount = 2
    [anArray release];                            // retainCount = 1, only one "left" is in self.results
}

- (void)dealloc {
    [results release];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...