NSObject +load 和 +initialize - 它们的作用是什么?

2023-11-27

我有兴趣了解导致开发人员覆盖 +initialize 或 +load 的情况。文档清楚地表明这些方法是由 Objective-C 运行时为您调用的,但这实际上是这些方法的文档所清楚的全部内容。 :-)

我的好奇心来自于查看 Apple 的示例代码 - MVCNetworking。他们的模型类有一个+(void) applicationStartup方法。它在文件系统上做一些内务处理,读取 NSDefaults 等等……并且,在尝试理解 NSObject 的类方法之后,看起来这个清洁工作可能可以放入 +load 中。

我确实修改了 MVCNetworking 项目,删除了 App Delegate 中对 +applicationStartup 的调用,并将内务处理位放入 +load...我的计算机没有着火,但这并不意味着它是正确的!我希望了解您必须调用的自定义设置方法与 +load 或 +initialize 之间的任何微妙之处、陷阱和问题。


对于+load文档说:

加载消息被发送到类和类别,它们都是 动态加载和静态链接,但前提是新加载的 类或类别实现了可以响应的方法。

如果您不知道所有单词的确切含义,这句话​​就很混乱并且难以解析。帮助!

  • “动态加载和静态链接”是什么意思?某些东西可以动态加载和静态链接吗,或者它们是互斥的吗?

  • “...新加载的类或类别实现了一个可以响应的方法” 什么方法?怎样回应?


至于+initialize,文档说:

初始化每个类仅调用一次。如果你想表演 类和类别的独立初始化 类,您应该实现加载方法。

我的意思是,“如果你尝试设置类......不要使用初始化。”好的。那么我什么时候或者为什么要覆盖初始化呢?


The load message

运行时发送load在类对象加载到进程的地址空间后不久,向每个类对象发送消息。对于属于程序可执行文件一部分的类,运行时会发送load在进程生命周期的早期就发出消息。对于共享(动态加载)库中的类,运行时会在共享库加载到进程的地址空间后立即发送加载消息。

此外,运行时仅发送load到一个类对象,如果该类对象本身实现了load方法。例子:

@interface Superclass : NSObject
@end

@interface Subclass : Superclass
@end

@implementation Superclass

+ (void)load {
    NSLog(@"in Superclass load");
}

@end

@implementation Subclass

// ... load not implemented in this class

@end

运行时发送load消息给Superclass类对象。确实如此not发送load消息给Subclass类对象,尽管Subclass继承该方法Superclass.

运行时发送load发送消息后向类对象发送消息load发送给该类的所有超类对象的消息(如果这些超类对象实现了load) 以及您链接到的共享库中的所有类对象。但你不知道你自己的可执行文件中的哪些其他类已收到load yet.

您的进程加载到其地址空间的每个类都会收到一个load消息,如果它实现了load方法,无论您的进程是否使用该类的任何其他用途。

您可以看到运行时如何查找load方法作为特殊情况_class_getLoadMethod of objc-runtime-new.mm,并直接从call_class_loads in objc-loadmethod.mm.

运行时还运行load它加载的每个类别的方法,即使同一类上的多个类别实现load。这很不寻常。通常,如果两个类别在同一个类上定义了相同的方法,则其中一个方法将“获胜”并被使用,而另一个方法将永远不会被调用。

The initialize Method

运行时调用initialize发送第一条消息之前类对象上的方法(除了load or initialize) 到类对象或类的任何实例。该消息是使用正常机制发送的,因此如果您的类没有实现initialize,但是从一个这样做的类继承,那么你的类将使用其超类的initialize。运行时将发送initialize首先发送给一个类的所有超类(如果超类尚未发送)initialize).

Example:

@interface Superclass : NSObject
@end

@interface Subclass : Superclass
@end

@implementation Superclass

+ (void)initialize {
    NSLog(@"in Superclass initialize; self = %@", self);
}

@end

@implementation Subclass

// ... initialize not implemented in this class

@end

int main(int argc, char *argv[]) {
    @autoreleasepool {
        Subclass *object = [[Subclass alloc] init];
    }
    return 0;
}

该程序打印两行输出:

2012-11-10 16:18:38.984 testApp[7498:c07] in Superclass initialize; self = Superclass
2012-11-10 16:18:38.987 testApp[7498:c07] in Superclass initialize; self = Subclass

由于系统发送initialize方法惰性地,除非您的程序实际将消息发送到类(或子类,或类或子类的实例),否则类不会接收消息。当你收到时initialize,你的进程中的每个类都应该已经收到load(如果合适的话)。

规范的实现方式initialize这是:

@implementation Someclass

+ (void)initialize {
    if (self == [Someclass class]) {
        // do whatever
    }
}

这种模式的要点是避免Someclass当它有一个未实现的子类时重新初始化自身initialize.

运行时发送initialize消息在_class_initialize函数于objc-initialize.mm。你可以看到它使用了objc_msgSend发送,这是正常的消息发送功能。

进一步阅读

查看迈克·阿什的周五问答关于这个话题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NSObject +load 和 +initialize - 它们的作用是什么? 的相关文章

  • 是否可以使用 UITableViewStylePlain 禁用 UITableView 中的浮动标题?

    我正在使用一个UITableView布局内容 页面 我使用表视图的标题来布局某些图像等 如果它们不浮动而是保持静态 就像样式设置为时那样 我更喜欢它UITableViewStyleGrouped 其他则使用UITableViewStyleG
  • UIPageViewController:获取当前页面

    在过去的几天里 我一直在努力解决这个问题 经过所有这些杂耍 我发现我所需要的只是数据源方法中的当前索引 以使用当前可见页码进行更新 我有这个UIPageViewController数据源方法 我需要使用当前索引来获取委托方法的当前可见页面p
  • NSTextField 委托通知——如何获取文本?

    我一直在尝试学习使用 Xcode 但我对如何注册感到困惑NSTextField已经改变 本质上 我有一个NSTextField和一个按钮 单击该按钮会填充字段中的文本 但是 我希望能够获取该字段的文本 而无需使用文本字段 操作 结束编辑时发
  • NSString cString 已弃用。还有什么选择呢?

    我还有一个新手问题 我编写了一段代码 将 NSString 转换为 NSMutableData 以模拟 webService 结果 然而事实证明 cString 已被弃用 你能帮我更换它吗 这是我的代码 NSString testXMLDa
  • iOS - 当应用程序被终止时处理静默推送通知

    我目前在 iOS 中遇到推送通知问题 我的应用程序收到包含标识符的静默推送通知 然后 该标识符用于从创建本地通知的远程服务器获取数据 据我所知 如果用户强制退出应用程序 即通过双击主页按钮并滑动关闭应用程序 则静默推送通知不会传递到 App
  • 未找到 ios 的 React 本机基本标头

    在 iOS 链接阶段 我开始看到我的 React Native 项目出现错误 反应本机版本 0 41 2 0 40 0 39 一切正常 我编辑了 Android 版本 React Native 代码没有改变 当这种链接错误开始出现并带有标题
  • 如何使用 Restkit 0.20.0 创建/发布新的托管对象到服务器?

    我很难找到创建新托管对象 设置其值以及使用 Restkit 保存到服务器的文档或示例 我有一篇 NSManagedObject 帖子 interface Post NSManagedObject property nonatomic ret
  • #import "xxx" 和 #import 有什么区别? [复制]

    这个问题在这里已经有答案了 可能的重复 include 和 include 文件名 有什么区别 https stackoverflow com questions 21593 what is the difference between i
  • 所有 UI 前面的透明 UIImageView

    首次启动我的应用程序后 我想向用户展示一些教程 以解释我的应用程序的功能 所以我需要设置一个带有一些箭头和标签的透明 UIImageView 其中主 UI 更具体地说 tabbarcontroler 中的 navigationviewcon
  • 如何使用 NSUndoManager 支持替换 UITextView 中的文本?

    我希望能够以编程方式替换 UITextView 中的某些文本 因此我将此方法编写为 UITextView 类别 void replaceCharactersInRange NSRange range withString NSString
  • 将 uiview 转换为 .png 图像

    我正在 iphone 上工作 我采用 UIView 的子类 并在绘制矩形方法中进行一些设计 我想将此视图转换为 png 格式 提前致谢 UIGraphicsBeginImageContext myView frame size myView
  • 如何消除圆形矩形按钮周围的间隙而不删除其周围的边框? [复制]

    这个问题在这里已经有答案了 顺便提一句 这可能看起来像是关于按钮阴影问题的问题的重复 但它们有单调的背景 在我的例子中 背景是一些图像 所以简单的边框不能解决问题 While making app for iPhone Pad I noti
  • 如何在 xcode 中从 nib 文件创建视图?

    我有以下代码来创建视图并将其放入滚动视图中以允许分页代码工作正常 但是我不能做的是从 nib 文件加载视图 换句话说 我想使用 initWithNibName 而不是 initWithFrame void createPageWithCol
  • 在 iOS 中以编程方式配置代理设置

    如何在 iOS 中以编程方式配置代理设置NSURLSession 我跟着这个link https stackoverflow com questions 28101582 how to programmatically add a prox
  • UIButton 图像调整大小/缩放以适合

    我有一个非常严重的问题 我不知道如何解决 我正在对 UIButtons 框架进行动画处理 当我对其进行动画处理时 我希望按钮中的图像缩放到与按钮相同的大小 它无需在我的 iPhone 模拟器上执行任何操作即可运行 但是当我在 iPad 模拟
  • -[MyClassName copyWithZone:] 无法识别的选择器发送到实例

    我的应用程序崩溃了 原因是 MyClassName copyWithZone 无法识别的选择器发送到实例 我有两节课 假设 Class1 和 Class2 Class1 看起来像 Class1 h interface Class1 NSOb
  • 如何在 iOS 中以编程方式在 UITableViewCells 中添加图像

    我需要添加不同的图像UITableViewCells以编程方式 我怎样才能做到这一点 我正在尝试一些代码 但图像不显示在UITableViewCells 这是我下面的代码 void viewDidLoad arrImages NSMutab
  • 具有自定义视图的相机

    我的应用程序使用相机 我想在相机预览上添加叠加层 例如 我想在使用相机时使用相框 还想添加一个用于相机操作的自定义栏 请帮助我做同样的事情 您可能正在尝试使用 UIImagePickerController 但我知道这个可以解决你的问题 您
  • 类型铸造自我

    以下自我转换对 ClassA 有何作用 这种种姓可以让你进入ClassA吗 A h类 interface ClassA NSObject NSUInteger someNumber ClassB classB property nonato
  • 不确定如何在使用故事板时正确子类化 UIApplication

    我想在 X 次用户不活动 没有触发触摸事件 后返回故事板的初始视图控制器 经过一些研究 我发现检测不活动的最常见方法是触发 NSTimer 并在事件触发时重置间隔 为了检测触发的事件 我们在 UIApplication 的子类中重写 UIA

随机推荐

  • Spring 转换服务:如何将 String 转换为 List

    我正在使用 Spring 的转换服务 并注册了我自己的转换器 public class MyTypeConverter implements Converter
  • 比较 2 个 wchar_t 数组

    我确信这非常简单 但我来自 C 背景 其中字符串很简单 现在我正在进入非托管世界 我很困惑 本质上 我使用 EnumDisplayDevices 来列出可用的设备 我想要定位特定的适配器 因此我需要将 DeviceString 和 Devi
  • JAXB 非法注释异常

    我是第一次使用 JAXB 在理解它要我做什么时遇到一些问题 我已经设置了一个类 它将成为相当大的 XML 的一部分 该类将表示 XML 文档的 标题 部分 package com somecompany jscentral xml inte
  • 并行集合中 scala 折叠的行为

    让我们多次运行以下代码行 Set 1 2 3 4 5 6 7 par fold 0 结果非常有趣 scala gt Set 1 2 3 4 5 6 7 par fold 0 res10 Int 8 scala gt Set 1 2 3 4
  • Javascript 中的一次迭代中的映射和排序?

    是否可以将数组映射到新数组并同时对其进行排序 而无需迭代两次 一次用于第一个数组上的映射 一次用于第二个数组上的排序 在使用这样的映射方法时 我一直尝试使用匿名函数对其进行排序 var arr 4 2 20 44 6 var arr2 ar
  • Jade 模板,包含中的变量范围

    我正在使用 Jade 没有 Express 仅用于静态 HTML 模板 我将其理解为能够创建部分 意味着范围不是问题 但情况似乎并非如此 我找不到对此使用的任何参考 案件 玉大师 5 html block vars var slug hom
  • 如何在 PHP 中发出 HTTP 请求而不等待响应

    PHP 中有没有办法进行 HTTP 调用而不等待响应 我不在乎回应 我只想做类似的事情file get contents 但在执行其余代码之前不等待请求完成 这对于在我的应用程序中引发某种 事件 或触发长进程非常有用 有任何想法吗 我之前接
  • 如何按行长度排序,然后按字母顺序反转

    我有一大堆 600 多个 搜索和替换术语 我需要将它们作为 sed 脚本在某些文件上运行 问题是搜索项不是正交的 但我认为我可以通过按行长度排序来摆脱它 即首先拉出最长的匹配项 然后按每个长度内的字母顺序排列 所以给定一组未排序的 aaba
  • glibcxx STL 在 std::valarray::sum() 的实现中是否不正确?

    我正在玩弄valarrays当我遇到某些问题时 我认为编译器的 STL 实现中存在错误 这是我可以制作的最小示例 include
  • REST 可以通过 FTP 实现吗?

    我和我的同事不同意 REST 可以通过 FTP 实现的说法 我相信 由于 REST 只是一种架构设计 因此它可以通过任何具有合适接口的协议来实现 例如 FTP 然而 他不同意 并认为目前除了 HTTP REST 之外 任何协议都不能实现 我
  • 为什么 Ember.run afterRender 不适用于 CSS 转换?

    根据我的理解 使用 CSS 过渡的一种方法是使用Ember run scheduleOnce afterRender 但是 对我来说 如果不添加超时 它就无法工作 这是在 Ember 1 0 0 中 View Em View extend
  • 如何使用循环在 C# 中将 pi 计算到 N 个位置

    我如何在 C 中计算 PI 到一定的小数位数 我希望能够将一个数字传递到一个方法中 并返回计算到该小数位数的 PI public decimal CalculatePi int places magic return pi Console
  • 可以使用属性启用/禁用 Spring Boot @RestController 吗?

    给定一个 标准 Spring Boot 应用程序 RestController eg RestController RequestMapping value foo produces application json charset UTF
  • 从 Three.js r.58 中的位移贴图计算法线?

    我正在使用 Three js r 58 中的普通着色器 我明白需要法线贴图 但是 我使用的是动态位移贴图 因此预先计算的法线贴图在这种情况下不起作用 我发现的所有光照置换贴图的示例都使用平面着色或预先计算的法线贴图 是否可以根据位移的顶点动
  • 如何对具有命名空间属性 href 的 SVG 元素使用 CSS 属性选择器?

    为什么我不能通过 href 属性选择元素 CSS Works svg image type overlay outline 3px solid blue Doesn t work svg image href temp outline 5p
  • 未找到合适的默认 RequestUpgradeStrategy

    我正在尝试在 Spring 上运行 Websocket 不是 STOMP 而是常规的 websocket 如图所示here 但是 按照教程进行操作后 我收到以下异常 org springframework beans factory Bea
  • 如何从 Java HTTPResponse 解析 JSON?

    我有一个用于刚刚发出的 Web 请求的 HttpResponse 对象 响应是 JSON 格式 所以我需要解析它 我可以用一种极其复杂的方式来做到这一点 但似乎必须有更好的方法 这真的是我能做的最好的事情吗 HttpResponse res
  • 将行添加到现有 UITableView 部分

    我正在尝试获取一些示例代码 了解如何将行添加到现有的UITableView 我正在尝试使用insertRowsAtIndexPaths 功能 tableView insertRowsAtIndexPaths addindexes withR
  • 当前 SynchronizationContext 不能用作 TaskScheduler

    我在用Tasks在我的 ViewModel 中运行长时间运行的服务器调用 并将结果编组回Dispatcher using TaskScheduler FromSyncronizationContext 例如 var context Task
  • NSObject +load 和 +initialize - 它们的作用是什么?

    我有兴趣了解导致开发人员覆盖 initialize 或 load 的情况 文档清楚地表明这些方法是由 Objective C 运行时为您调用的 但这实际上是这些方法的文档所清楚的全部内容 我的好奇心来自于查看 Apple 的示例代码 MVC