Цель-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];
}
теперь мы загружаем записи сотрудников только тогда, когда они нам действительно нужны. Если они уже загружены, мы не делаем никакой дополнительной работы (кроме одного вызова метода). Если мы не нужны платежные записи, тогда нам вообще не нужно делать работу.
класс работает только тогда, когда он имеет ... и ждет до последней минуты, чтобы сделать работу. Это " ленивый!"