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

Ленивый экземпляр в разработке Objective-C/iPhone

Быстрый вопрос... Ну, я понимаю, что все свойства начинаются как nil в Objective-C и что отправка сообщения в nil ничего не делает, поэтому вы должны инициализировать с помощью [[Class alloc] init]; перед отправкой сообщения во вновь созданное свойство. Однако, как насчет того, если я не отправляю сообщения этому свойству, или если я устанавливаю свойство, используя self.property = something? Нужно ли мне также назначать init в этих случаях? Кроме того, свойства UI начинаются как ноль, например, свойство UILabel, которое вы вытаскиваете из раскадровки? Нужно ли им назначать init?

Спасибо всем, кто отвечает

4b9b3361

Ответ 1

Стэннер неплохо объяснил, что не нужно выделять объекты init, которые уже были созданы.

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

Итак, вы хотите свойство NSMutableArray. Вы можете выделить init в каком-либо методе перед его использованием, но тогда вам нужно беспокоиться о том, "вызывает ли этот метод, прежде чем мне понадобится мой массив"? или "я собираюсь называть это снова случайно и повторно инициализировать его".

Таким образом, безопасное место для этого - это свойство getter. Он вызывается каждый раз, когда вы получаете доступ к свойству.

.h
@property (nonatomic, strong) NSMutableArray* myArray;

.m
@synthesize myArray = _myArray;

- (NSMutableArray*)myArray
{
    if (!_myArray) {
        _myArray = [[NSMutableArray alloc] initWithCapacity:2];
    }
    return _myArray;
}

Каждый раз, когда вы обращаетесь к этому свойству, он говорит: "Существует ли myArray? Если нет, создайте его. Если это так, просто верните то, что у меня есть".

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

Ответ 2

Реальность - это когда вы делаете self.myProperty = [[Class alloc] init], вы не инициализируете свою собственность. Скорее, вы инициализируете объект, на который вы указываете свое свойство (на самом деле указатель), на которое указывает. Поэтому, если у вас уже есть объект, который был выделен и инициализирован, вам не нужно снова выделять /init, и вы можете сделать self.myProperty = object;

Свойства пользовательского интерфейса не начинаются с нуля, это связано с тем, что при добавлении элементов в построитель интерфейса представление содержит элементы, которые вы добавляете, и эти объекты автоматически инициализируются для вас. Это означает, что если вы создаете IBOutlets и соединяете их с некоторыми свойствами, вам не нужно выделять /init.

Надеюсь, это было полезно.

Ответ 3

У меня нет опыта работы с Storyboards, но я знаю, что когда вы создаете объекты через xib файл, все объекты создаются надлежащим образом, когда вы указываете контроллеру представления использовать xib файл. Поэтому вам не нужно беспокоиться о том, как выделять/инициализировать эти объекты в коде.

Что касается использования self.property = <something>, это зависит от того, что something. Если что-то есть какой-либо существующий объект, вам не нужно выполнять инициализацию alloc на этом объекте, так как синтаксис self.property = ... вызывает метод setterter, который будет сохранять, копировать, назначать и т.д. Новое значение для свойства соответствующим образом.

Теперь любой существующий объект может быть объектом alloc/init'ed или автореализованным объектом, полученным из удобного метода (например, NSString stringWithFormat).

Как указал Каан Дедеоглу, синтаксис self.property = ... указывает (и сохраняет) ivar на объект в памяти, и вам решать инициализировать этот объект, если он еще не создан.

Ответ 4

Нет, вам не нужно [[Класс alloc] инициализировать свойства в вашем методе init.

Однако я бы рекомендовал вам явно установить их в Nil в методе init для ясности.