Управление памятью переменной, переданной в качестве параметра - PullRequest
0 голосов
/ 29 февраля 2012

Я пишу класс плагина для фреймворка.

Мой интерфейс определен так:

@interface Blah : NSObject<SomeDelegate> 
{
    @private 
        NSString* _callbackID;
}

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

В первом методе, который называется, я делаю что-то вроде этого:

- (void) blah:(NSArray*)blahArray 
{
    _callbackID = [blahArray objectAtIndex:0];
    MyViewController *vc = [[MyViewController alloc] init];
    vc.someDelegate = self;
    [self.viewController presentModalViewController:vc animated:YES];
    [vc release];
}

Как делегат, мой плагин Blah класс получит обратный вызов от MyViewController, где ему нужно будет использовать этот _callbackID.

  1. Правильно ли я обрабатываю закрытую переменную и правильно ли я присваиваю ей значение?
  2. Я понимаю, что мне не нужно управлять NSString с blahArray, поскольку я не создавал его, это правильно?
  3. Если бы вызов blah был асинхронным, что остановило бы очистку NSArray в вызове объекта blah, не оставив мне ничего в _callbackID? Откуда мне знать, что это был случай?
  4. Если NSString _callbackID затем назначается существующему объекту, который не контролируется классом, вызывающим blah, нужно ли его скопировать, чтобы вызывающий класс не очистил его?

Ответы [ 2 ]

2 голосов
/ 29 февраля 2012

1. Правильно ли я обрабатываю приватную переменную и правильно ли ей присваиваю значение?

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

@property (nonatomic, copy) NSString *_callbackID;

И затем компилятор автоматически сгенерирует методы get / set, добавив это в вашу реализацию:

@sythesize _callbackID;

Тогда вы можете просто написать:

self._callbackID = [blahArray objectAtIndex:0];

, который прозрачно вызывает автоматически сгенерированный метод set_callbackID, который будет копировать значение (из-за подсказки copy в дескрипторе свойства).

2. Я понимаю, что мне не нужно управлять строкой NSSt из blahArray, поскольку я не создал ее, это правильно?

Вы не несете ответственности за освобождение , но если вы хотите сохранить его, вам нужно либо retain, либо copy. Как только вы это сделаете, вы несете ответственность за его освобождение (подробнее см. Ответ Гилада).

3. Если бы вызов blah был асинхронным, что остановило бы очистку NSArray в объекте, вызывающем blah, оставив меня без _callbackID? Откуда мне знать, что это был случай?

К настоящему времени вы, вероятно, поняли, что без retain или copy переменная может быть освобождена во время ее использования. Вот почему вы должны сделать это самостоятельно. Вы бы знали, если переменная была выпущена из-под вас, потому что ваше приложение зависло бы с EXC_BAD_ACCESS; -).

4. Если NSString _callbackID затем назначается существующему объекту, который не контролируется вызывающим классом blah, нужно ли его копировать, чтобы вызывающий класс не очистил его?

Да. И если вы хотите убедиться, что переменная остается в течение всей функции, вы можете написать [[myVar retain] autorelease]. Затем он будет автоматически освобожден в конце цикла выполнения (или всякий раз, когда текущий пул автоматического выпуска сбрасывается).

2 голосов
/ 29 февраля 2012
_callbackID = [[blahArray objectAtIndex:0] copy];

и внутри вашей сделки:

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

Таким образом, вам все равно, что владелец делает с этим объектом. В общем, вы всегда должны создавать копии строки, так как строка может быть NSMutableString и может измениться. Если вы хотите сохранить текущее значение, всегда используйте «копировать», а не «сохранять».

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