Подтвердить что ты не робот

Objective-C копия неизменяемого объекта. Сразу: ARC-совместимая реализация

Как я и предполагал, это должно отлично работать для неизменяемого объекта в ARC:

- (id) copyWithZone:(NSZone *)zone {
    return self;
}

Но если мне нужна глубокая копия, я должен написать что-то вроде этого:

- (id) copyWithZone:(NSZone *)zone {
    Immutable *copy = [[Immutable alloc] initWithStr:str];
    return copy;
}

Итак, если бы я считал правильным, ARC понимал бы ситуацию (1) и (2) и принимал правильное решение о "+1" для ссылок.

Я прав?

4b9b3361

Ответ 1

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

- (id) copyWithZone:(NSZone *)zone {
    return [self retain];
}

Это то, что я получил после миграции:

- (id) copyWithZone:(NSZone *)zone {
    return self;
}

Это волшебство, когда ARC работает иногда, но, похоже, мы просто должны верить, что он хорошо справится с этой задачей.: -)

Ответ 2

Автоматический подсчет ссылок, как указано в спецификации, соответствует стандартным методам именования Cocoa. Это означает, что предполагается, что методы с префиксами init, copy и new возвращают объекты, которыми владеет вызывающий (+1 счетчик ссылок). Поэтому, если вы возвращаете объект из одного из этих методов, ARC автоматически обрабатывает его таким образом, поскольку вы больше не можете явно его сохранить.

Единственным проблемным случаем вокруг этого, о котором говорил Apple, была бы сторонняя структура, использующая ручной подсчет кода, где авторы не соблюдали стандартные соглашения об именах. Примером, который они дали, был метод, возвращающий строку с автореализацией под названием copyRightString. Это будет выведено из строя на ARC, потому что оно предположит, что объект с подсчитанным объектом +1 возвращается из такого метода.

Вы можете заставить ARC обрабатывать этот метод специальным образом, используя модификатор, подобный следующему:

-(NSString*) copyRightString NS_RETURNS_NON_RETAINED;

У Mugunth Kumar есть немного больше подробностей об этом в его записи о миграции ARC.