Вопрос управления памятью - PullRequest
2 голосов
/ 28 февраля 2010

Мне показалось, что я овладеваю управлением памятью Какао, но сейчас у меня есть чему поучиться.

Взгляните на этот класс, который я написал:

Word.h

#import <UIKit/UIKit.h>


@interface Word : NSObject {
    NSString *word;
    NSMutableArray *wordArray;
}

@property (nonatomic ,retain) NSString *word;
@property (nonatomic ,retain) NSMutableArray *wordArray;

@end

Word.m

#import "Word.h"


@implementation Word

@synthesize word, wordArray;

- (void)setWord:(NSString *)aWord {
    NSMutableArray *newValue = [[NSMutableArray alloc] init];
    self.wordArray = newValue;
    [newValue release];

    for (int i = 0 ;i < [aWord length] ;i++) {
        NSString *character = [[NSString alloc] init];
        character = [NSString stringWithFormat:@"%C",[aWord characterAtIndex:i]];
        [wordArray addObject:character];
        //[character release];
    }
}

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

@end

Как вы видите, я заполняю массив, когда устанавливаю строку. Я делаю это в цикле for, вытаскивая символ строки и помещая их в новую выделенную строку. Затем я помещаю эту строку в массив, а затем я должен освободить строку. И здесь я делаю это неправильно, потому что я высвобождаю значение, которое я помещаю в массив. когда позже я пытаюсь использовать массив, его нет.

Как мне это сделать? нехорошо делать «персонаж» свойством и освобождать его в dealloc, потому что оно просто временное.

Ответы [ 2 ]

6 голосов
/ 28 февраля 2010

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

Теперь stringWithFormat возвращает автоматически выпущенную строку, на которую затем указывает character. Этот объект не должен быть выпущен вами, но это то, что происходит в закомментированной строке. Так что этот цикл будет лучше как:

for (int i = 0 ;i < [aWord length] ;i++) {
        NSString* character = [NSString stringWithFormat:@"%C",[aWord characterAtIndex:i]];
        [wordArray addObject:character];
}
3 голосов
/ 28 февраля 2010

Помимо проблемы управления памятью, знаете ли вы, что вы переопределили функцию установки для свойства word?

Когда вы @synthesize свое свойство word, методы setter и getter генерируются позадисцены, так что уже есть функции для - (void)setWord:(NSString *)aWord; и - (NSString *)word;. Вы можете прочитать об этом в учебнике Objective-C или Документация языка программирования .

Поскольку вы создали функцию (void)setWord:(NSString *)aWord;, она переопределяет созданный установщик.Поскольку вы на самом деле не устанавливаете переменную word, ваше свойство «сломано».

Например, возможно, переписать его как:

#import "Word.h"

@implementation Word

@synthesize word, wordArray;

- (void)setWord:(NSString *)aWord {
    // set the word iVar
    if (aWord != word) {
        [aWord retain]; // I prefer [aWord copy];
        [word release];
        word = aWord;
    }

    NSMutableArray *newValue = [[NSMutableArray alloc] init];

    for (int i = 0 ;i < [aWord length] ;i++) {
        NSString *character = [NSString stringWithFormat:@"%C",[aWord characterAtIndex:i]];
        [wordArray addObject:character];

    }
    // Now that you have created the newArray, set it to the property
    self.wordArray = newValue;
    [newValue release];
}

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

@end

Редактировать

Почему я написал, что предпочел [aWord copy] над [aWord retain]?Потому что я бы объявил свойства как copy, а не retain.

Изменчивость может быть болью.Предположим, что вместо передачи NSString* в aWord каким-то образом передается NSMutableString*.Это возможно, потому что NSMutableString является подклассом NSString.Предположим также, что другая часть программы изменила значение этой строки (в конце концов, оно изменяемое ).Теперь мы изменили свойство класса Word внешне.Это нарушает инкапсуляцию.

Имеет смысл использовать @property (copy)… для классов коллекций.

Хороший ответ вы можете прочитать здесь .

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