Changed +load method order in Xcode 7
TL,DR: It's xctest's fault, not objc's.
This is because of how the xctest
executable (the one that actually runs the unit tests, located at $XCODE_DIR/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Agents/xctest
loads its bundle.
Pre-Xcode 7, it loaded all referenced test bundles before running any tests. This can be seen (for those that care), by disassembling the binary for Xcode 6.4, the relevant section can be seen for the symbol -[XCTestTool runTestFromBundle:]
.
In the Xcode 7 version of xctest
, you can see that it delays loading of testing bundles until the actual test is run by XCTestSuite
, in the actual XCTest
framework, which can be seen in the symbol __XCTestMain
, which is only invoked AFTER the test's host application is set-up.
Because the order of these being invoked internally changed, the way that your test's +load
methods are invoked is different. There were no changes made to the objective-c-runtime's internals.
If you want to fix this in your application, you can do a few things. First, you could manually load your bundle using +[NSBundle bundleWithPath:]
, and invoking -load
on that.
You could also link your test target back to your test host application (I hope you're using a separate test host than your main application!), which would make it be automatically loaded when xctest loads the host application.
I would not consider it a bug, it's just an implementation detail of XCTest.
Source: Just spend the last 3 days disassembling xctest
for a completely unrelated reason.
XCode 7 XCTest(Kiwi) +load category methods called twice
It appears that you have included the same class extension in both the main application binary and in your test bundle. This would also explain why you see a separate setup of static dispatch_once tokens on the second load.
Why this is the case may be a number of things:
- .mm-file is included in both targets
- Xcode loads the test binary twice due to changes in test-procedure
- Both test target and application link to the same .a file containing the
+load
method
Order of events when loading a View in iOS
Other than cases where the order of messages is clearly defined or strongly implied by names, you should avoid depending on any particular order. For example, you can reasonably expect -viewWillAppear
to be called before -viewDidAppear
for any given view, but don't expect one view's -viewWillAppear
to be called in any particular order with respect to any message sent to a different view.
If you need help figuring out how to implement a particular feature without depending on order, please ask. But again, unless the order of invocation is documented or blatantly obvious from the method names, don't expect a particular order.
Update: I don't see exactly what's going wrong in the code you added, but perhaps a few suggestions will help:
Is your
isDisappearing
variable an instance variable of your view controller, a global variable, or what? If it's an instance variable, figure out how it's being changed. If it's a global variable, well... don't do that.Be sure that you're heeding the warning in the docs to the effect that
-textViewShouldEndEditing:
is only advisory, and that the view may stop editing no matter what you return.Try temporarily removing the iToast stuff. If the crash still happens, at least you've eliminated that as a source of problems. If it stops happening, you'll have narrowed your search.
Identify the cause of the crash. (This should really be first on the list.) Crashes don't just happen mysteriously -- there's a reason that it happens. Find that reason, and you're 85% done. Start by examining the stack trace when the crash occurs. If that doesn't provide enough clues, place a breakpoint somewhere before the line that causes the crash and start stepping until you crash. If all else fails, start logging messages to trace execution and monitor your assumptions.
What exactly is your view controller A doing in its
-viewWillAppear
method? Could that be part of the problem? Could you move that code to, say,-viewDidAppear
instead?
Edit app in order to support both IOS 7 and 8
Changing deployment target will not work.
Please keep deployment target to the lowest supported iOS version.
Also, Apple provides backward compatibility. So the deprecated methods will work.
For best result use respondsToSelector
.
Try to replace deprecated methods but with caution. Keep your old methods as is. And conditionally give support for iOS 8 and above.
Hope i am helpful.
Thanks
Is there a quick way to fold and unfold comments in xcode 7?
Code-folding block comments does not work in Xcode 7 - 7.2.1 in Swift files.
You can, however, hack it by using an empty closure to surround the comments. This will also work with multiple line comments too.
_ = { /* Comment
myCommented.code
*/ }
Definitely a hack, but could save you lots of scrolling around.
Is there a change in the processing of the order of events in iOS 8.1 and xCode 6
Don't ever assume that the order of internal Apple events in the runloop will be in order, especially when they are related to independent objects.
In this case you have the UITextField delegate method firing, and the UIButton touch. Don't link the two in your code. If you need the data to be saved before the email is sent, please make sure that the data is indeed saved before the email is sent.
One way to do it is to have a bool like dataIsModified
that you set to true whenever any data is modified, and reset when the save is done. Then in the email sending method, check if dataIsModified, then save again.
NSObject +load and +initialize - What do they do?
The load
message
The runtime sends the load
message to each class object, very soon after the class object is loaded in the process's address space. For classes that are part of the program's executable file, the runtime sends the load
message very early in the process's lifetime. For classes that are in a shared (dynamically-loaded) library, the runtime sends the load message just after the shared library is loaded into the process's address space.
Furthermore, the runtime only sends load
to a class object if that class object itself implements the load
method. Example:
@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
The runtime sends the load
message to the Superclass
class object. It does not send the load
message to the Subclass
class object, even though Subclass
inherits the method from Superclass
.
The runtime sends the load
message to a class object after it has sent the load
message to all of the class's superclass objects (if those superclass objects implement load
) and all of the class objects in shared libraries you link to. But you don't know which other classes in your own executable have received load
yet.
Every class that your process loads into its address space will receive a load
message, if it implements the load
method, regardless of whether your process makes any other use of the class.
You can see how the runtime looks up the load
method as a special case in the _class_getLoadMethod
of objc-runtime-new.mm
, and calls it directly from call_class_loads
in objc-loadmethod.mm
.
The runtime also runs the load
method of every category it loads, even if several categories on the same class implement load
. This is unusual. Normally, if two categories define the same method on the same class, one of the methods will “win” and be used, and the other method will never be called.
The initialize
Method
The runtime calls the initialize
method on a class object just before sending the first message (other than load
or initialize
) to the class object or any instances of the class. This message is sent using the normal mechanism, so if your class doesn't implement initialize
, but inherits from a class that does, then your class will use its superclass's initialize
. The runtime will send the initialize
to all of a class's superclasses first (if the superclasses haven't already been sent 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;
}
This program prints two lines of output:
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
Since the system sends the initialize
method lazily, a class won't receive the message unless your program actually sends messages to the class (or a subclass, or instances of the class or subclasses). And by the time you receive initialize
, every class in your process should have already received load
(if appropriate).
The canonical way to implement initialize
is this:
@implementation Someclass
+ (void)initialize {
if (self == [Someclass class]) {
// do whatever
}
}
The point of this pattern is to avoid Someclass
re-initializing itself when it has a subclass that doesn't implement initialize
.
The runtime sends the initialize
message in the _class_initialize
function in objc-initialize.mm
. You can see that it uses objc_msgSend
to send it, which is the normal message-sending function.
Further reading
Check out Mike Ash's Friday Q&A on this topic.
How to re-order segues in initial view's tabbar controller in xcode 4.5?
The positions in each view are associated with the positions on the bottom bar of the Tab Bar Controller. If you reorder that bar you will reorder your views. You can reorder them by drag and drop on your interface builder.
In your example just select Home in your Tab Bar Controller and drag it to the first position.
If you have problems dragging and dropping try to select first your Tab View Controller or exit your XCode and open it again (like @thepumpkin1979 and @Rick pointed out).
Related Topics
How to Express Strings in Swift Using Unicode Hexadecimal Values (Utf-16)
Embed a Uiviewcontroller in a Navigationcontroller Using Segues
Sending a Private Message to Your Friends via Facebook iOS Sdk
Missing Marketing Icon Xcode Bug
iOS Autolayout Multi-Line Uilabel
Uicollectionview Insert Cells Above Maintaining Position (Like Messages.App)
How to Dismiss the iOS Keyboard
Detect Backspace Event in Uitextfield
How to Have a Dynamic List of Views Using Swiftui
iOS Push Notification Banner Shown Twice for a Single Push
Avcapturesession Audio Doesn't Work for Long Videos
How to Logout User Using Facebook Authentication Using Swift and iOS
Swiftui: Deleting Last Row in Foreach
What Is Build Object File Extension in iOS
Error: Cuicatalog: Invalid Asset Name Supplied: (Null), or Invalid Scale Factor:2.000000
Why Is There an Frame Rectangle and an Bounds Rectangle in an Uiview
iOS Is It a Static or a Dynamic Framework
How to Figure Out Which Url Is Being Blocked by App Transport Security