Objective-C и создание нового объекта в куче - PullRequest
2 голосов
/ 20 января 2012

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

Проблема.

//From GraphObject.m
-(void) addNode
{
    GraphNode *newNode = [[GraphNode alloc] initWithId:count];
    [graphNodes addObject:newNode];
    NSLog(@"Node %i added", count);
    count++;
}

Этот фрагмент взят из моего класса GraphObject и является местом, где программа прерывается. Разрывается на первой строке блока. Этот метод предназначен для создания объекта GraphNode и помещения его в NSMutableArray (с именем graphNodes) класса GraphObject. Переменная count просто отслеживает, сколько узлов было добавлено. Привыкнув к C ++, мне трудно понять, почему он не просто помещает объект в кучу, а позволяет мне его использовать. Btw. Точно такая же строка функционирует правильно, если я помещу ее в основную часть, что немного сбивает меня с толку.

Если бы кто-нибудь мог объяснить, что я делаю неправильно, это было бы очень признательно.

EDIT: Вот метод initWithId. Я начинаю подозревать, что причина может быть здесь. Должен ли он возвращать указатель на себя?

-(id) initWithId:(int)n
{
    nodeId = [NSNumber numberWithInt:n];
    neighbourNodes = [NSMutableArray arrayWithCapacity:8];
    return self;
}

Утечка памяти, о которой вы упоминаете (yAak), я предполагаю, что речь идет о создании массивов GraphNode в этом методе. Но не будет ли это решено, когда я удаляю массив, в который я их помещаю? Если я удаляю их тем же способом, то, насколько я вижу, в массив ничего не помещается. Кроме того, я извиняюсь за то, что не публикую сообщения об ошибках, поскольку я новичок в xcode, но я просто не вижу ни одного. Сборка прошла успешно и просто говорит, что программа остановилась на определенной строке кода.

EDIT2 (И решение): Ну, вот странный сюрприз. Я удалил / вырезал код и запустил программу один раз, а затем вставил обратно тот же самый код, и теперь он работает нормально. Это одна стабильная IDE прямо здесь. Еще раз спасибо за ответы, я уверен, что скоро вернусь сюда.

Ответы [ 2 ]

2 голосов
/ 20 января 2012

Ваш инициализатор:

-(id) initWithId:(int)n
{
    nodeId = [NSNumber numberWithInt:n];
    neighbourNodes = [NSMutableArray arrayWithCapacity:8];
    return self;
}

должно выглядеть так:

- (id)initWithId:(int)n
{
    self = [super init]; /* << or whatever the designated initializer of the superclass is */
    if (nil != self) {
        nodeId = [[NSNumber alloc] initWithInt:n];
        neighbourNodes = [[NSMutableArray alloc] initWithCapacity:8];
    }
    return self;
}

Что касается кучи, то каждый созданный вами экземпляр NSObject подсчитывается и находится в куче. Clang даже не позволит вам создавать объекты в стеке (это будет делать GCC).

Когда вы думаете, что ваша куча испорчена или ваши объекты или их члены освобождены преждевременно, помните, что есть куча инструментов диагностики памяти / подсчета ссылок: Зомби - это одно, GuardMalloc и писанина - другие. Конечно, «Утечки» - это тоже хорошая проверка.

0 голосов
/ 20 января 2012

Утечки, NSZombies и т. Д. Все полезные инструменты. Но когда особенно. когда вы плохо знакомы с языком (а иногда даже когда нет), лучший способ исправить проблемы управления памятью, как это:

1) читать это: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html

2) снова посмотрите на ваш код.

3) перечитайте это: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html

[... и т.д.]

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

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

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