Цель-C: что такое ленивый класс?

глядя на исходный код библиотеки времени выполнения Objective-C, особенно на objc-runtime-new.мм, я видел некоторые функции и даже комментарии, которые относились к ленивым и не-ленивым классам. Кажется, что классы, которые не имеют +load метод называется ленивыми классами, но я не уверен в этом и, скорее всего, это неправильно. После поиска в Google я ничего не нашел о ленивых классах на Objective-C.

Итак, что такое ленивый класс в Objective-C? Делает В Obj-C имеют эту функцию? Связано ли это с наличием +load метод в реализации класса? В файле, связанном выше, система выполнения вызывает функцию _getObjc2NonlazyClassList чтобы получить список не-ленивых классов из изображения. Почему нет

2 ответов


я нашел ответ: это все о реализации класса или не +load метод.

все классы, реализованные в данном файле изображения, имеют ссылку в списке, хранящемся в "__DATA, __objc_classlist, regular, no_dead_strip" раздел двоичного файла. Этот список позволяет системе выполнения отслеживать все классы, хранящиеся в таком файле. Однако не все классы должны быть реализованы при запуске программы. Вот почему, когда класс реализует +load метод, он также имеет ссылку в списке, хранящемся в .

и _getObjc2NonlazyClassList возвращает список классов, которые реализуют +load метод и так называемые non-lazy. _getObjc2ClassList возвращает список всех классов в файле изображения, включая классы, которые не имеют +load метод (и называются ленивыми) и не-ленивые. Не-ленивые классы должны быть реализованы при запуске программы. Ленивые классы, с другой стороны, не должны быть реализованы немедленно. Это может быть отложено до тех пор, пока класс получает сообщение в первый раз, например (вот почему их следует считать "ленивыми").

то же самое верно для категорий, кстати.


"ленивый" используется в двух разных контекстах.

это не то, что вы имеете в виду здесь.

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

например, предположим, что у нас есть класс, который делает объект employee.

 @implementation Employee
 - (id) initWithID: (IdentificationCode*) ident
 {
    self =[super init]
    if (self) {
         _records=[self retrieveEmployeeRecordsFor: ident];
         _identification=ident;
         }
    return self;
}

это нормально, но извлечение всех записей из базы данных может быть медленным. И иногда нам не нужно делать работу. Например:

- (BOOL) isFounder
{
     if (indent.number<10) return YES;
     return NO;
}

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

 .....
 if ([thisEmployee isFounder]) {
      [self sendCandyTo: thisEmployee.identification];
      }

С другой стороны, иногда нам нужно они:

- (NSArray*) payments
{
    return [self.records retrievePayStubs];
    }

Итак, если мы строим сотрудника только для вызова isFounder, мы тратим поиск базы данных. Но мы не можем просто пропустить это, потому что payments в ней нуждается.

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

- (void) load
{
    if (records) return;
    self.records=[self retrieveEmployeeRecordsFor: ident];
}

- (NSArray*) payments
{
    [self load];
    return [self.records retrievePayStubs];
    }

теперь мы загружаем записи сотрудников только тогда, когда они нам действительно нужны. Если они уже загружены, мы не делаем никакой дополнительной работы (кроме одного вызова метода). Если мы не нужны платежные записи, тогда нам вообще не нужно делать работу.

класс работает только тогда, когда он имеет ... и ждет до последней минуты, чтобы сделать работу. Это " ленивый!"