www.bifa365.comc独身方式Singleton的经文达成

在objective-c中使用+(void)initialize可以方便的实现独身模式(单例模式)。

apple对这两个方法的描述:

load 和 initialize 中,都不用调用 super的方法


文档说明:

  • (void)initialize

+ (void)load;

The runtime sends initialize to each class in a program exactly one
time just before the class, or any class that inherits from it, is
sent its first message from within the program. (Thus the method may
never be invoked if the class is not used.) The runtime sends the
initialize message to classes in a thread-safe manner. Superclasses
receive this message before their subclasses.

The runtime sends initialize to each class in a program exactly one
time just before the class, or any class that inherits from it, is
sent its first message from within the program. (Thus the method may
never be invoked if the class is not used.) The runtime sends the
initialize message to classes in a thread-safe manner. Superclasses
receive this message before their subclasses.

The order of initialization is as follows:

  1. All initializers in any framework you link to.

  2. All+loadmethods in your image.

  3. All C++ static initializers and
    C/C++__attribute__(constructor)functions in your image.

  4. All initializers in frameworks that link to you.

In addition:

示例代码如下:

  • (void)load

A class’s+load method is called after all of its superclasses’+load methods.

static MySingleton *sharedSingleton;

+ (void)initialize
{
    static BOOL initialized = NO;
    if(!initialized)
    {
        initialized = YES;
        sharedSingleton = [[MySingleton alloc] init];
    }
}

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.
The order of initialization is as follows:
1 All initializers in any framework you link to.
2 All +load methods in your image.
3 All C static initializers and C/C attribute(constructor)
functions in your image.
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.
• A category +load method is called after the class’s own +load
method.
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.
initialize和load的区别在于:load是只要类所在文件被runtime引用就会被调用,而initialize是在类或者其子类的第一个方法被调用前调用。所以如果类没有被引用进项目,就不会有load调用;但即使类文件被引用进来,但是没有使用,那么initialize也不会被调用。
它们的相同点在于:方法只会被runtime调用一次。
initialize和load的调用顺序:SuperClass > SubClass, Class > Class
Category。Initialize
是通过msg_send消息机制,所以当调用子类的Initialize时会自动调用父类的。不需要通过[super initialize]调用。然而load是通过函数指针的形式调用。分类中的initialize会覆盖掉类中的。分类中的load则不会覆盖掉子类中的。
示例代码在这里

A category +load method is called after the class’s own +load method(包括所有子类).

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.


+ (void)initialize;

Initializes the class before it receives its first message.

The runtime sendsinitializeto 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. 

Superclasses receive this message before their subclasses.

The runtime sends the initialize message to classes in a thread-safe
manner. 

That is, initialize is run by the first thread to send a message to a
class, and any other thread that tries to send a message to that class
will block until initialize completes.

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 blocking manner, it’s important to
limit method implementations to the minimum amount of work necessary
possible. 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.


结论: load,先调父类,后调子类,最后调用分类;initialize,像其他方法一样,分类覆盖原有方法

@implementation superClass

+(void)load

{

www.bifa365.com,NSLog(@”superClass load”);

}

+(void)initialize {

if (self == [ViewController self]) {

NSLog(@”xxx”);

}

@end

@implementation superClass(ct)

+(void)load

{

NSLog(@”category load”);

}

+(void)initialize

{

NSLog(@”category initialize”);

}

@end

@implementation subClassA

+(void)load{

NSLog(@”subClassA load”);

}

@end

@implementation subClassB

+(void)load

{

NSLog(@”subClassB load”);

}

@end

NSLog(@”%@”, NSStringFromClass( [self class]));

}

@end

2017-03-12 22:28:17.561 load&initializeTest[4816:135672] superClass
load

2017-03-12 22:28:17.564 load&initializeTest[4816:135672] subClassA
load

2017-03-12 22:28:17.564 load&initializeTest[4816:135672] subClassB
load

2017-03-12 22:28:17.564 load&initializeTest[4816:135672] category load

2017-03-12 22:28:17.647 load&initializeTest[4816:135672] category
initialize

2017-03-12 22:28:17.655 load&initializeTest[4816:135672] category
initialize

2017-03-12 22:28:17.656 load&initializeTest[4816:135672] category
initialize

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website