OC 类的加载和初始化

来源:互联网 发布:aes加密算法java 编辑:程序博客网 时间:2024/06/05 15:19


////  Person.h//  类的加载和初始化////  Created by LiuWei on 15/4/15.//  Copyright (c) 2015年 LiuWei. All rights reserved.//#import <Foundation/Foundation.h>@interface Person : NSObject// 当程序启动的时候, 就会加载一次项目中所有的类, 类加载完毕后就会调用 + load方法// 如果有继续关系,则先加载父类的 +load 方法 然后依次加载子类的 + load方法+ (void)load;// 只有第一次使用这个类的时候 才会加载 +initialize 方法+(void)initialize;- (void)test;@end

////  Person.m//  类的加载和初始化////  Created by LiuWei on 15/4/15.//  Copyright (c) 2015年 LiuWei. All rights reserved.//#import "Person.h"@implementation Person+ (void)load{    NSLog(@"Person ---- load");}+ (void)initialize{    NSLog(@"Person ---- initialize");}- (void)test{    NSLog(@"person test!");}@end


////  Student.h//  类的加载和初始化////  Created by LiuWei on 15/4/15.//  Copyright (c) 2015年 LiuWei. All rights reserved.//#import "Person.h"@interface Student : Person// 当程序启动的时候, 就会加载一次项目中所有的类, 类加载完毕后就会调用 + load方法// 如果有继续关系,则先加载父类的 +load 方法 然后依次加载子类的 + load方法+ (void)load;// 只有第一次使用这个类的时候 才会加载 +initialize 方法+ (void)initialize;- (void)test;@end


////  Student.m//  类的加载和初始化////  Created by LiuWei on 15/4/15.//  Copyright (c) 2015年 LiuWei. All rights reserved.//#import "Student.h"@implementation Student+ (void)load{    NSLog(@"Student ---- load");}+ (void)initialize{    NSLog(@"Student ---- initialize");}- (void)test{    NSLog(@"Student test");}@end



////  main.m//  类的加载和初始化////  Created by LiuWei on 15/4/15.//  Copyright (c) 2015年 LiuWei. All rights reserved.//#import <Foundation/Foundation.h>#import "Person.h"#import "Student.h"int main(){    NSLog(@"do nothing!");        Person *p = [[Person alloc]init];    Person *p2 = [[Person alloc]init];            Student *s = [[Student alloc]init];    Student *s2 = [[Student alloc]init];        [p test];    [p2 test];        [s test];    [s2 test];        return 0;}



断点定在第15行代码,调试运行, 现在代码运行到主函数main中, 程序定格在第15行, 15行是将要执行但还没有执行的代码, 这时观察输出窗口显示

在进入程序(主函数main)之前,就已经加载了全部的类信息, 类信息加完成后会调用一次 +load方法, 由以上输出信息顺序可以知道,类信息加载的顺序为先

加载父类,然后再依次加载子类


单步运行断在第18行代码, 在第17行,第一次创建了一个Person类对象 p , 输出窗口显示在创建对象的过程中调用了Person的类方法

initialize;

\\

继续单步断点定在21行, 在第18行代码中,又生成了第二个Person类对象, 观察输出窗口并没有第二次调用 Person的类方法initialize; 说明 类方法initialize只有

在第一次使用类信息时才会被调用一次.



同样 子类Student也只有在第一次被使用时才会调用一次Student的类方法 initialize;


官主文档对这两个类方法的解释如下


+ (void)load

Description

Invoked whenever a class or category is added to the Objective-C runtime; implement this method to perform class-specific behavior upon loading.

// 类或分类中定义的load方法都会被添加到OC运行时; 实现这个方法是为了在加载中执行类的特定行为


The load message is sent to classes and categories that are both dynamically loaded and statically linked, but only if the newly loaded class or category implements a method that can respond.

// 动态加载和静态链接时,load消息被发送到类和分类中. 但是只有在最近加载的类或分类中实现的相关方法才会响应

The order of initialization is as follows:

// 初始化的顺序如下

  1. All initializers in any framework you link to. // 在你所链接的任何框架中的所有初始化器
  2. All +load methods in your image. // 在你镜像中的所有 +load方法
  3. All C++ static initializers and C/C++ __attribute__(constructor) functions in your image. // 在你镜像中的所有C++静态初始化器和C/C++ __attribute__(constructor) 函数
  4. All initializers in frameworks that link to you. 所有链接到你程序的框架中的初始化器

In addition: // 另外

  • A class’s +load method is called after all of its superclasses’+load methods. // 类的+load方法在所有父类的+load方法调用之后调用
  • A category +load method is called after the class’s own+load method. // 分类的+load方法在类的+load方法调用之后调用

In a custom implementation of load you can therefore safely message other unrelated classes from the same image, but any load methods implemented by those classes may not have run yet.

因此在load的一般实现中, 你可以安全的发送消息给相同镜像中其它无关的类,  但是通过这些类实现的load方法可能还没有运行.

Availability

OS X (10.0 and later)

Declared In

NSObject.h

Reference

NSObject Class Reference



+ (void)initialize

Description

Initializes the class before it receives its first message.

在它接收到第一个消息之前初始化类


The runtime sends initialize to each class in a program just before the class, or any class that inherits from it, is sent its first message from within the program. The runtime sends the initialize message to classes in a thread-safe manner. Superclasses receive this message before their subclasses. The superclass implementation may be called multiple times if subclasses do not implement initialize—the runtime will call the inherited implementation—or if subclasses explicitly call[super initialize]. If you want to protect yourself from being run multiple times, you can structure your implementation along these lines:

+ (void)initialize {

  if (self == [ClassName self]) {

    // ... do the initialization ...

  }

}

Because initialize is called in a thread-safe manner and the order of initialize being called on different classes is not guaranteed, it’s important to do the minimum amount of work necessary in initialize methods. Specifically, any code that takes locks that might be required by other classes in their initialize methods is liable to lead to deadlocks. Therefore you should not rely on initialize for complex initialization, and should instead limit it to straightforward, class local initialization.


initialize is invoked only once per class. If you want to perform independent initialization for the class and for categories of the class, you should implementload methods.

Availability

OS X (10.0 and later)

Declared In

NSObject.h

Reference

NSObject Class Reference


0 0