Objective c 目标C:什么是懒惰班?

Objective c 目标C:什么是懒惰班?,objective-c,lazy-evaluation,objective-c-runtime,Objective C,Lazy Evaluation,Objective C Runtime,查看Objective-C运行时库源代码,尤其是在,我看到了一些函数甚至注释,它们引用了惰性类和非惰性类。似乎没有+load方法的类被称为惰性类,但我不确定这一点,很可能这是不对的。在谷歌上搜索之后,我没有在Objective-C上找到任何关于懒惰类的内容 那么,Objective-C中的懒惰类是什么?Obj-C是否具有此功能?它是否与类的实现中存在+load方法有关?在上面链接的文件中,运行时系统调用一个名为\u getObjc2NonlazyClassList的函数,以便从映像中获取非惰性类

查看Objective-C运行时库源代码,尤其是在,我看到了一些函数甚至注释,它们引用了惰性类和非惰性类。似乎没有
+load
方法的类被称为惰性类,但我不确定这一点,很可能这是不对的。在谷歌上搜索之后,我没有在Objective-C上找到任何关于懒惰类的内容

那么,Objective-C中的懒惰类是什么?Obj-C是否具有此功能?它是否与类的实现中存在
+load
方法有关?在上面链接的文件中,运行时系统调用一个名为
\u getObjc2NonlazyClassList
的函数,以便从映像中获取非惰性类的列表。为什么没有
\u getObjc2LazyClassList
函数?

在两种不同的上下文中使用“Lazy”

第一,在批评类设计时,认为类是无效的——它没有充分证明它的存在。人们也把这种类称为“瘦”。这可能不是你在这里的意思。

其次,惰性求值惰性实例化意味着类只在实际需要时执行求值属性或初始化自身的工作

例如,假设我们有一个生成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;
}
另一方面,有时我们需要它们:

- (NSArray*) payments
{
    return [self.records retrievePayStubs];
    }
因此,如果我们构建一个员工只是为了调用
isFounder
,那么我们就浪费了数据库查找。但我们不能跳过这一步,因为
支付
需要它

我们要做的是将数据库查找从构造函数中取出,并将其放入
load
方法中

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

- (NSArray*) payments
{
    [self load];
    return [self.records retrievePayStubs];
    }
现在,我们只在实际需要时加载员工记录。如果它们已经被加载,我们不做任何额外的工作(除了一个方法调用)。如果我们从不需要付款记录,那么我们根本不需要做这项工作


该类只在必要时才工作,并一直等到最后一分钟才开始工作。这是“懒惰!”

我找到了答案:这是关于类实现还是不是
+load
方法

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

- (NSArray*) payments
{
    [self load];
    return [self.records retrievePayStubs];
    }
给定映像文件中实现的所有类在存储在二进制文件部分的列表中都有一个引用。该列表允许运行时系统跟踪存储在该文件中的所有类。然而,并非所有的类都需要在程序启动时实现。这就是为什么当一个类实现
+load
方法时,它在
中存储的列表中也有一个引用“\uuuuu DATA,\uuuu objc\u nlclslist,regular,no\u dead\u strip”
部分

因此,
\u getObjc2NonlazyClassList
检索实现
+load
方法的类列表,这些类被称为非惰性类
\u getObjc2ClassList
检索图像文件中所有类的列表,包括没有
+load
方法(称为lazy)和非lazy方法的类。非惰性类必须在程序启动时实现。另一方面,懒惰类不需要立即实现。例如,这可能会延迟到类第一次收到消息为止(这就是它们被认为是“懒惰”的原因)


顺便说一句,类别也是如此。

可能是从插件加载的类。也许可以查看关于plugins/dyld/动态加载代码的文档。你确定这意味着类是惰性的,而不仅仅是列表吗?我同意@JoshCaswell的观点,因为在运行时源代码的后面,有关于类中惰性加载的引用。它几乎肯定是指列表,而不是一个“懒惰”的类。@JoshCaswell@lxt我还认为它是一个类列表,应该稍后加载,我不确定。但在代码的某些地方,我发现了注释“//realization non-lazy类(对于+加载方法和静态实例)”。下面是对
\u getObjc2NonlazyClassList
的调用,它似乎得到了一个懒惰类列表(我还不确定),而不是一个懒惰类列表。感谢您的回答,Mark。那是我想象的。因此,类被认为是懒惰的,因为它的行为。但是有件事仍然困扰着我:存在着
\u getObjc2NonlazyClassList
函数,它似乎加载了在映像文件中存储为非惰性的类。这就像有一个方面使类在编译时不懒惰一样。或者可能只是命名法:从图像文件加载的所有类都被认为是非惰性的……请注意,对于类别,如果这些类别位于外部库中,则必须使用
all\u load
链接器标志。这可能几乎是正确的,但我看到过包含uu objc\u nlclslist的MachO图像,但不包含uu objc_类列表部分。