Что увеличивает показатель удержания объекта?

Вот код, который я имею в виду.

// Person.h

@interface Person : NSObject {
    NSString *firstName;
    NSString *lastName;
}
@end

// Person.m

@implementation Person
- (id)init {
    if (![super init]) return nil;
    firstName = @"John";
    lastName = @"Doe";
}
@end

// MyClass.m

@implementation MyClass
    .....
- (NSArray *)getPeople {
    NSMutableArray *array = [[NSMutableArray alloc] init];

    int i;
    for (i = 0; i < 10; i++) {
        Person *p = [[Person alloc] init];
        [array addObject:p];
    }

    return array;
}
    .....
@end

Теперь, я знаю, что в этом примере кода отсутствует управление памятью. Что потребуется?

В цикле getPeople я назначаю Person (preserveCount 1), а затем добавляю его в массив. Счет сохранения теперь равен 2, правильно? Если это два, я должен быть [p release] после добавления его в массив, возвращая значение keepCount в 1?

Правильно ли я в том, что ответственность вызывающего абонента заключается в том, чтобы освободить массив, возвращаемый методом? (Что также освободит память персонажа и их переменных экземпляра, если их количество будет равно 1).

Я прочитал документ управления памятью Apple, но я думаю, что я больше всего не понимаю, это то, что увеличивает количество объектов, удерживающих счет? Я думаю, что я понимаю идею того, кто несет ответственность за освобождение. Это основное правило, согласно Apple:

Вы получаете право собственности на объект, если его создаете с помощью метода, имя которого начинается с "alloc" или "new" или содержит "copy" (например, alloc, newObject или mutableCopy), или если вы отправляете сохранить сообщение. Вы несете ответственность за отказ от владения собственными вами объектами с помощью выпуска или авторекламы. В любой другой момент, когда вы получаете объект, вы не должны его отпускать.

Предложение bobDevil "только беспокоиться о том, что количество удержаний, которое вы добавляете в элемент явно, заставило его щелкнуть по мне. После прочтения политики собственности в Apple, по сути, объект/метод, создавший новый объект, является ответственным за освобождение/его/интерес к нему. Правильно ли это?

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

Если это неверно, сообщите мне.

Ответы

Ответ 1

Вы правы, что счетчик сохранения равен 2 после добавления его в массив. Однако вы должны только беспокоиться о том, что вы сохраняете счет, который вы добавляете к элементу явно.

Сохранение объекта - это контракт, в котором говорится: "Я не с тобой, не уходи". Основное эмпирическое правило (есть исключения, но они обычно документируются) заключается в том, что вы являетесь владельцем объекта при назначении объекта или создании копии. Это означает, что вам задан объект со значением удержания 1 (не автореализованным). В этих двух случаях вы должны освободить его, когда закончите. Кроме того, если вы когда-либо явно сохраняете объект, вы должны его освободить.

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

Person *p = [[Person alloc] init]; //retain 1, for you
[array addObject:p]; //array deals with p however it wants
[p release]; //you're done, so release it

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

return [array autorelease];

Изменить:  Правильно, если вы его создадите, вы должны его освободить. Если вы вкладываете в него проценты (через сохранение), вы должны его освободить.

Ответ 2

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

Обычно методы

factory предоставляют вам автореализованный объект (например, [NSMutableArray array]), вам нужно будет специально сохранить это, чтобы поддерживать его в течение некоторого времени.).

Что касается NSArray и NSMutableArray addObject:, кому-то придется комментировать. Я считаю, что вы относитесь к классам как к черным ящикам с точки зрения того, как они обрабатывают свое управление памятью как шаблон дизайна, поэтому вы никогда не сможете явно опубликовать что-то, что вы передали в NSArray. Когда он разрушается, он должен обрабатывать декремент самого счета.

Вы также можете получить некоторое неявное сохранение, если вы объявите свои ivars как свойства, такие как @property (сохранить) suchAndSuchIvar, и используйте @synthesize в своей реализации. Synthesize в основном создает сеттеры и геттеры для вас, и если вы вызываете (сохраняете) конкретно, сеттер собирается сохранить переданный ему объект. Это не всегда очевидно, потому что сеттеры могут быть структурированы следующим образом:

Person fart = [[Person alloc] init];
fart.firstName = @"Josh"; // this is actually a setter, not accessing the ivar
                          // equivalent to [fart setFirstName: @"Josh"], such that
                          // retainCount++

Edit:

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

   for (i = 0; i < 10; i++) {
       Person *p = [[Person alloc] init];
       [array addObject:p];
       [p release];
   }

Джош

Ответ 3

Вы должны/не быть/беспокоиться об удержании счета. Это внутренне реализовано. Вам нужно только заботиться о том, хотите ли вы "владеть" объектом, сохранив его. В приведенном выше коде массив должен владеть объектом, а не вы (вне цикла, в котором вы даже не ссылаетесь на него, кроме массива). Поскольку у вас есть [[Person alloc] init], вам необходимо его освободить.

Таким образом,

Person *p = [[Person alloc] init];
[array addObject:p];
[p release];

Кроме того, вызывающий "getPeople" не должен владеть массивом. Это соглашение. Сначала вы должны авторейтировать его.

NSMutableArray *array = [[[NSMutableArray alloc] init] autorelease];

Вы захотите прочитать документацию Apple по управлению памятью: http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html