Accessors / Getters и Lazy Initialization - PullRequest
       58

Accessors / Getters и Lazy Initialization

2 голосов
/ 14 сентября 2010

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

-(UIImage *) image{

    if(image == nil){
        if(self.data == nil){
            [self performSelectorInBackground: @selector(loadImage) withObject: nil]
        }else{
            self.image = [UIImage imageWithData: self.data];
        }
    }

    return image;
}

-(NSData *) data {

    if(data == nil){
        if(self.image == nil){
            [self performSelectorInBackground: @selector(loadData) withObject: nil]
        }else{
            self.data = UIImageJPEGRepresentation(self.image, 0.85);
        }
    }

    return data;
}

Я должен подчеркнуть, что использование изображения, представленное здесь, является примером, и мысли о том, что делать в этом конкретном примере, менее важны, чем в общем случае.

Ответы [ 3 ]

3 голосов
/ 14 сентября 2010

Во-первых, не будьте слишком умны для своего же блага.Если вы хотите преодолеть некоторое узкое место, сначала измерьте и убедитесь, что оно действительно есть.Я считаю, что и UIImage, и NSData выполняют некоторую внутреннюю ленивую загрузку, так что ваш код может быть практически бесполезным.Во-вторых, даже если вы действительно хотите сделать что-то подобное вручную, попробуйте разделить код кэширования на отдельный класс, чтобы не загрязнять код основного класса.

Правил в отношении этого нет.аксессоры (по крайней мере, нет, о которых я знаю), потому что люди не лениво загружают аксессоры.Иногда меня ловит бесконечный цикл, вызванный ленивым [UIViewController loadView] в сочетании с [UIViewController view], но это все.

2 голосов
/ 14 сентября 2010

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

0 голосов
/ 14 сентября 2010

то, что вы на самом деле делаете в этом примере, может занять много времени для загрузки;Лучше всего убедиться, что это потокобезопасно.

Более того, было бы еще лучше, если бы вы сделали объект данных реальным поставщиком данных (обычно с использованием протоколов), отдельно от класса, и сделали изображениеКонтейнер разоблачает, что он обрабатывает лениво загруженный объект (что может вызвать протест у некоторых людей).

в частности, вы можете вызвать загрузку данных / изображения от провайдера, вызвать его из awakeFromNib (например) - тогда загрузчик выключится и загрузит данные во вторичный поток (особенно, если он загружен),предоставить поставщику данных обратный вызов, чтобы сообщить представлению о том, что изображение готово (обычно с использованием протоколов).как только представление получит неархивированное изображение, аннулируйте провайдер данных.

наконец, если вы имеете дело с ресурсами приложения, «система» будет кешировать часть этого для вас, так что вы пытаетесь работать противто, что уже оптимизировано за кулисами. Короче говоря,

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

...