In what order methods +initialize and +load called?
Lets imagine that we have two classes:
@interface First : NSObject
@end
@interface Second : NSObject
@end
@implementation First
+(void)load
{
NSLog(@"This must be called first");
}
@end
@implementation Second
+(void)load
{
NSLog(@"And this must be called second");
}
@end
We have +load methods in each class. If we run this code, This must be called first will be first and And this must be called second will be second.
What determines the order in which the +load methods of this classes are called? In my experiment, if I move @implementation of second class before @implementation of first class - And this must be called second is printed first and This must be called first is printed second. Is this means that +load order depends only from order in source code?
In my real case I have precompiled framework with custom +load (some code are called before main() and I see logs from it), and I need to execute my code before this code (and as I understand - I can place it into +load, but I don't know how to change order). Or may be I can call my code before framework code with some other technique?
objective-c runtime objective-c-runtime
add a comment |
Lets imagine that we have two classes:
@interface First : NSObject
@end
@interface Second : NSObject
@end
@implementation First
+(void)load
{
NSLog(@"This must be called first");
}
@end
@implementation Second
+(void)load
{
NSLog(@"And this must be called second");
}
@end
We have +load methods in each class. If we run this code, This must be called first will be first and And this must be called second will be second.
What determines the order in which the +load methods of this classes are called? In my experiment, if I move @implementation of second class before @implementation of first class - And this must be called second is printed first and This must be called first is printed second. Is this means that +load order depends only from order in source code?
In my real case I have precompiled framework with custom +load (some code are called before main() and I see logs from it), and I need to execute my code before this code (and as I understand - I can place it into +load, but I don't know how to change order). Or may be I can call my code before framework code with some other technique?
objective-c runtime objective-c-runtime
add a comment |
Lets imagine that we have two classes:
@interface First : NSObject
@end
@interface Second : NSObject
@end
@implementation First
+(void)load
{
NSLog(@"This must be called first");
}
@end
@implementation Second
+(void)load
{
NSLog(@"And this must be called second");
}
@end
We have +load methods in each class. If we run this code, This must be called first will be first and And this must be called second will be second.
What determines the order in which the +load methods of this classes are called? In my experiment, if I move @implementation of second class before @implementation of first class - And this must be called second is printed first and This must be called first is printed second. Is this means that +load order depends only from order in source code?
In my real case I have precompiled framework with custom +load (some code are called before main() and I see logs from it), and I need to execute my code before this code (and as I understand - I can place it into +load, but I don't know how to change order). Or may be I can call my code before framework code with some other technique?
objective-c runtime objective-c-runtime
Lets imagine that we have two classes:
@interface First : NSObject
@end
@interface Second : NSObject
@end
@implementation First
+(void)load
{
NSLog(@"This must be called first");
}
@end
@implementation Second
+(void)load
{
NSLog(@"And this must be called second");
}
@end
We have +load methods in each class. If we run this code, This must be called first will be first and And this must be called second will be second.
What determines the order in which the +load methods of this classes are called? In my experiment, if I move @implementation of second class before @implementation of first class - And this must be called second is printed first and This must be called first is printed second. Is this means that +load order depends only from order in source code?
In my real case I have precompiled framework with custom +load (some code are called before main() and I see logs from it), and I need to execute my code before this code (and as I understand - I can place it into +load, but I don't know how to change order). Or may be I can call my code before framework code with some other technique?
objective-c runtime objective-c-runtime
objective-c runtime objective-c-runtime
asked Dec 30 '18 at 0:17
Stanislav ChernischukStanislav Chernischuk
339520
339520
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
You really can't rely on order, nor can you effectively control order. By design. +load should happen before the +initialize of that class, but they order of the two is seemingly indeterminate across multiple classes (which I find slightly surprising, but well within the rules).
This is a big part of why you shouldn't do any heavy lifting in +load or +initialize. They really should only be used sparingly and only for initializing a small bit of highly localized state. Touching other significant subsystems is dangerous because you'll be changing initialization order and behavior in ways that might break the system. Shouldn't, but it might, it can, and it has in the past.
Instead, you really should try to have a "start here" point in your framework code that the client explicitly calls into.
Might be worth also pointing out that there's also a guarantee that a base class's +load and +initialize are called before its subclasses'.
– uliwitness
Jan 12 at 9:17
add a comment |
+load methods are invoked by the objc runtime as part of the image loading process (you can see this by breaking in your load method and printing a stacktrace).
The order in which +load methods are invoked seems to depend on the order of the objc class lists generated by clang.
If you look at the source code of the objc runtime, you'll see that load_images (the function called by dyld), calls prepare_load_methods to get a list of all objc classes in an image. prepare_load_methods calls _getObjc2NonlazyClassList, which fetches the objc classlist from the __objc_nlclslist section in the image.
load_images then calls call_load_methods, which goes through all loaded classes and invokes their +load methods.
Yes; the order is an implementation detail subject to change. Even if you were to back into the current order, that may not be stable over releases. As well, any dynamic loading that comes into play will have additional loading phases.
– bbum
Jan 2 at 18:01
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53974352%2fin-what-order-methods-initialize-and-load-called%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You really can't rely on order, nor can you effectively control order. By design. +load should happen before the +initialize of that class, but they order of the two is seemingly indeterminate across multiple classes (which I find slightly surprising, but well within the rules).
This is a big part of why you shouldn't do any heavy lifting in +load or +initialize. They really should only be used sparingly and only for initializing a small bit of highly localized state. Touching other significant subsystems is dangerous because you'll be changing initialization order and behavior in ways that might break the system. Shouldn't, but it might, it can, and it has in the past.
Instead, you really should try to have a "start here" point in your framework code that the client explicitly calls into.
Might be worth also pointing out that there's also a guarantee that a base class's +load and +initialize are called before its subclasses'.
– uliwitness
Jan 12 at 9:17
add a comment |
You really can't rely on order, nor can you effectively control order. By design. +load should happen before the +initialize of that class, but they order of the two is seemingly indeterminate across multiple classes (which I find slightly surprising, but well within the rules).
This is a big part of why you shouldn't do any heavy lifting in +load or +initialize. They really should only be used sparingly and only for initializing a small bit of highly localized state. Touching other significant subsystems is dangerous because you'll be changing initialization order and behavior in ways that might break the system. Shouldn't, but it might, it can, and it has in the past.
Instead, you really should try to have a "start here" point in your framework code that the client explicitly calls into.
Might be worth also pointing out that there's also a guarantee that a base class's +load and +initialize are called before its subclasses'.
– uliwitness
Jan 12 at 9:17
add a comment |
You really can't rely on order, nor can you effectively control order. By design. +load should happen before the +initialize of that class, but they order of the two is seemingly indeterminate across multiple classes (which I find slightly surprising, but well within the rules).
This is a big part of why you shouldn't do any heavy lifting in +load or +initialize. They really should only be used sparingly and only for initializing a small bit of highly localized state. Touching other significant subsystems is dangerous because you'll be changing initialization order and behavior in ways that might break the system. Shouldn't, but it might, it can, and it has in the past.
Instead, you really should try to have a "start here" point in your framework code that the client explicitly calls into.
You really can't rely on order, nor can you effectively control order. By design. +load should happen before the +initialize of that class, but they order of the two is seemingly indeterminate across multiple classes (which I find slightly surprising, but well within the rules).
This is a big part of why you shouldn't do any heavy lifting in +load or +initialize. They really should only be used sparingly and only for initializing a small bit of highly localized state. Touching other significant subsystems is dangerous because you'll be changing initialization order and behavior in ways that might break the system. Shouldn't, but it might, it can, and it has in the past.
Instead, you really should try to have a "start here" point in your framework code that the client explicitly calls into.
answered Dec 30 '18 at 7:05
bbumbbum
156k23251349
156k23251349
Might be worth also pointing out that there's also a guarantee that a base class's +load and +initialize are called before its subclasses'.
– uliwitness
Jan 12 at 9:17
add a comment |
Might be worth also pointing out that there's also a guarantee that a base class's +load and +initialize are called before its subclasses'.
– uliwitness
Jan 12 at 9:17
Might be worth also pointing out that there's also a guarantee that a base class's +load and +initialize are called before its subclasses'.
– uliwitness
Jan 12 at 9:17
Might be worth also pointing out that there's also a guarantee that a base class's +load and +initialize are called before its subclasses'.
– uliwitness
Jan 12 at 9:17
add a comment |
+load methods are invoked by the objc runtime as part of the image loading process (you can see this by breaking in your load method and printing a stacktrace).
The order in which +load methods are invoked seems to depend on the order of the objc class lists generated by clang.
If you look at the source code of the objc runtime, you'll see that load_images (the function called by dyld), calls prepare_load_methods to get a list of all objc classes in an image. prepare_load_methods calls _getObjc2NonlazyClassList, which fetches the objc classlist from the __objc_nlclslist section in the image.
load_images then calls call_load_methods, which goes through all loaded classes and invokes their +load methods.
Yes; the order is an implementation detail subject to change. Even if you were to back into the current order, that may not be stable over releases. As well, any dynamic loading that comes into play will have additional loading phases.
– bbum
Jan 2 at 18:01
add a comment |
+load methods are invoked by the objc runtime as part of the image loading process (you can see this by breaking in your load method and printing a stacktrace).
The order in which +load methods are invoked seems to depend on the order of the objc class lists generated by clang.
If you look at the source code of the objc runtime, you'll see that load_images (the function called by dyld), calls prepare_load_methods to get a list of all objc classes in an image. prepare_load_methods calls _getObjc2NonlazyClassList, which fetches the objc classlist from the __objc_nlclslist section in the image.
load_images then calls call_load_methods, which goes through all loaded classes and invokes their +load methods.
Yes; the order is an implementation detail subject to change. Even if you were to back into the current order, that may not be stable over releases. As well, any dynamic loading that comes into play will have additional loading phases.
– bbum
Jan 2 at 18:01
add a comment |
+load methods are invoked by the objc runtime as part of the image loading process (you can see this by breaking in your load method and printing a stacktrace).
The order in which +load methods are invoked seems to depend on the order of the objc class lists generated by clang.
If you look at the source code of the objc runtime, you'll see that load_images (the function called by dyld), calls prepare_load_methods to get a list of all objc classes in an image. prepare_load_methods calls _getObjc2NonlazyClassList, which fetches the objc classlist from the __objc_nlclslist section in the image.
load_images then calls call_load_methods, which goes through all loaded classes and invokes their +load methods.
+load methods are invoked by the objc runtime as part of the image loading process (you can see this by breaking in your load method and printing a stacktrace).
The order in which +load methods are invoked seems to depend on the order of the objc class lists generated by clang.
If you look at the source code of the objc runtime, you'll see that load_images (the function called by dyld), calls prepare_load_methods to get a list of all objc classes in an image. prepare_load_methods calls _getObjc2NonlazyClassList, which fetches the objc classlist from the __objc_nlclslist section in the image.
load_images then calls call_load_methods, which goes through all loaded classes and invokes their +load methods.
answered Dec 30 '18 at 18:51
LukasLukas
1,02222033
1,02222033
Yes; the order is an implementation detail subject to change. Even if you were to back into the current order, that may not be stable over releases. As well, any dynamic loading that comes into play will have additional loading phases.
– bbum
Jan 2 at 18:01
add a comment |
Yes; the order is an implementation detail subject to change. Even if you were to back into the current order, that may not be stable over releases. As well, any dynamic loading that comes into play will have additional loading phases.
– bbum
Jan 2 at 18:01
Yes; the order is an implementation detail subject to change. Even if you were to back into the current order, that may not be stable over releases. As well, any dynamic loading that comes into play will have additional loading phases.
– bbum
Jan 2 at 18:01
Yes; the order is an implementation detail subject to change. Even if you were to back into the current order, that may not be stable over releases. As well, any dynamic loading that comes into play will have additional loading phases.
– bbum
Jan 2 at 18:01
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53974352%2fin-what-order-methods-initialize-and-load-called%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown