Xcode 4.3 / iOS 5.1 - xcode4.3

I want to run my app on the iPad...I upgraded to Xcode 4.3 and iOS 5.1 and the app doesn't work anymore. The strange thing is that the app don't reach the entry point, the main method is not called. Have you got any ideas what the reason could be?
int main(int argc, char *argv[])
{
NSLog(#"test main"); //not visible in debugger
}
I know it is not much information but I don't know what info I should give

You need to move your NSLog call into your AppDelegate. Put it into the applicationDidFinishLaunching method. The reason you can't NSLog in main is that the core foundation libraries have not yet been loaded there.

Related

Objective-c: How to build funkyoverlaywindow starting with main.m

I'm looking at an Objective-C sample project at:
https://developer.apple.com/library/mac/samplecode/FunkyOverlayWindow/Introduction/Intro.html
I don't understand how main.m passes control to the other classes/objects.
Let me explain what I'm trying to do. I'm trying to build that app, step by step. My first step was to get main.m to compile. I believe this is the starting point for most applications. I don't know what to add/compile next, because main.m does't mention/refer to any of the classes in that project.
Any ideas?
The entry point in Objective-C programs is the function called main(). See the following code from main.m
int main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **)argue);
}
The main() function begins by calling a function named NSApplicationMain() that is cocoa framework function and not shown to user, which is functionally similar to the following:
void NSApplicationMain(int argc, char *argv[])
{
[NSApplication sharedApplication];
[NSBundle loadNibNamed:#"myMain" owner:NSApp];
[NSApp run];
}
Thus, [NSBundle loadNibNamed:#"myMain" owner:NSApp] is called by NSApplicationMain function and in this time, #"myMain" is identifier for Main Interface(as MainMenu.xib within sample source)
finally MainMenu.xib is run, and then OverlayWindow that is main window of MainMenu.xib will be run.
I appreciate, and understand perfectly, how you could not want to use Xcode - especially if, like me, you come from a Unix/GCC/Makefile environment. However, there are some things that are really quite hard to do without the Xcode GUI and linking buttons and widgets to your code is one of those things.
In Xcode, you click the button in your user interface and drag a line to the code attached to it - these are called IBOutlets and IBActions. So, my first suggestion is to Google those two terms.
Secondly, I recommend you watch this video on YouTube to understand what the XIB/NIB is and how to link it to your code and then you can try and do it without Xcode once you get the concept... video showing linking buttons to code.

EAAcessory errors while closing session with iOS 6.0 GM

There is a MFI device that is connected to iPhone 4S (6.0 GM) or to iPad (6.0 GM) via Bluetooth (2.1 + EDR). The project was built on Xcode 4.5 GM. When the app gets EAAccessoryDidDisconnectNotification it will send message [_eaSessionController closeSession];. All these worked nice in iOS 5.1.1 or earler. But on iOS6 with this message I got logs as follows:
-[NSCondition dealloc]: condition (<NSCondition: 0x2e5640> '(null)') deallocated while still in use
Break on _NSLockError() to debug.
Any ideas?
I came across the same issue. This warning is thrown when calling [NSStream close] upon receiving an EAAccessoryDidDisconnectNotification. There should be also some data exchange between the two devices just before the disconnection.
Breaking on _NSLockError will show that at the moment the object is deallocated, some of the threads spawned by the external accessory framework are waiting on conditions. One of those certainly waits on the condition that is being freed, which explains the warning thrown on the console.
I also noticed that the number of threads created by the external accessory framework keeps on growing each time the accessory disconnects then connects, and they seem to be just leaking.
It seems to me that somehow, the external accessory framework does not properly free the resources it allocates, which results in a lot of mess. One of the subsequent effects of this are crashes that happen inside one of those leaked threads during a call to OSAtomicCompareAndSwap64.
I managed to reproduce the issue using a basic sample in which the streams are scheduled on the main thread to avoid any thread management inside the application. I believe it's an accessory management bug on iOS 6 that Apple should be aware of. I'll report it and wait for what they have to say.
Meanwhile, I wonder if anyone of you guys has managed to make any progress on this.
Thanks,
There is no such trouble in iOS 6.1+. To fix this for iOS 6.0 and iOS 6.0.1 please use next solution:
Please note: this is only temp solution allow your users with iOS 6.0 and 6.0.1 continue use your app.
There is a simple hack to avoid application crashes: just create new category and override dealloc method (NSCondition) for iOS 6.0 and iOS 6.0.1:
#import "NSCondition+LeakDealloc.h"
#import <objc/runtime.h>
#implementation NSCondition (LeakDealloc)
- (void) safeDealloc
{
float sVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (sVersion < 6.0 || sVersion >= 6.1)
{
[self safeDealloc];
}
}
+ (void) load
{
method_exchangeImplementations(class_getInstanceMethod(self, #selector(dealloc)), class_getInstanceMethod(self, #selector(safeDealloc)));
}
#end
This solution make new leak, after 20 min tests and about 50 BG/FG swithces instruments shows 10 NSCondition leaks (960 Bytes), BUT no one crash!
The issue has been fixed in iOS 6.1.
There are no more leaking NSCondition or external accessory threads. Apple seem to having fixed the issue properly.

iPhone - Debugging from simulator will not load source files, but shows disassembly instead

I just started doing iPhone dev. At the moment I'm trying to fix a bug which exists in an already built app. The main function looks as follows:
#import <UIKit/UIKit.h>
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
This seems pretty typical from what I understand; I'm guessing UIApplicationMain is the main loop, which the source files that have been created for the app specifically connects to via the use of delegates/function pointers in Objective-C (note, while I'm quite proficient in C++, I hardly know much about iOS or Objective-C).
So, what I'd like to know is how I can step through my source files and track down the calculation bug I'm experiencing for this app. Unfortunately, all I receive is disassembly when stepping into the UIApplicationMain, and while I know the very basics of asm and can interpret it (for the most part), I'd rather not unless I absolutely have to - especially considering the fact that the debugger appears to be outputting AT&T syntax (NOTE: if it's possible to change the asm syntax to Intel, I'd appreciate it if someone could state how to do that).
Thanks.
You can put breakpoints on every line by clicking on the gray space between the code and the project explorer on the left. When running, upon encountering a breakpoint the simulator or device will stop running and the code will show up. Then hit either the down arrow button that will show up on the upper left of the debugging window at the bottom to go line by line, which will show asm when appropriate, or hit the right-pointing arrow which will run until the next breakpoint is hit. You can disable breakpoints by deleting them individually or by toggling the breakpoints button at the top.
The main function in iOS is almost identical in all projects. It just serves to get the ball rolling. Here is a good tutorial for debugging especially crashes in Xcode. debugging tutorial
(Answer to NOTE not the actual question)
xcode can be set to use gdb (in scheme settings):
simply add to your .gdbinit
(which is located in your home dir ) :
"set disassembly-flavor intel"
for lldb there might be something similar

Preprocessor Directive in xib?

Despite searching all over the place, I can't find the answer to my question. So let's see how good y'all are. :)
I'm working on an app that uses an NSPopover which is only available in 10.7 Lion but I want the app to compile for 10.5 and higher. I'm using a preprocessor directive to wrap the related popover code which seems to do the trick... However, the last piece I'm still getting errors on is the .zib in Interface Builder. How do I go about cleaning up the errors shown in the Issues Navigator stating "Class Unavailable: NSPopover on Mac OS X versions prior to 10.7"?
#ifdef __MAC_OS_X_VERSION_MAX_ALLOWED
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
#property (assign) IBOutlet NSPopover *popover;
}
#endif
#endif
The above works in xxx.h and xxx.m's, but how do I get around the .xib errors?
Despite the error (Red), it builds successfully. However am I wrong to expect the 10.7 features (popover) to work in 10.7 because they don't... What am I missing here?
You shouldn't use preprocessors for this but check for availability at runtime using NSClassFromString(). The preprocessor runs at compile time, thus it won't detect what system the app is being run on.
Create three nibs, one for each of 10.5, 10.6 and 10.7 and load the one you need (or do it in code), but pick which one at run time, not compile time, e.g.
MyVC *vc = nil;
if (NSClassFromString(#"NSPopover"))
{
vc = [NSViewController initWithNibName:#"MyVC-Lion" bundle:nil];
}
else if (/* check for 10.6+ only features */)
{
vc = [NSViewController initWithNibName:#"MyVC-SL" bundle:nil];
}
else
{
vc = [NSViewController initWithNibName:#"MyVC" bundle:nil];
}
// ...
Not a real answer to your question, apologies, but 2 possible workarounds: isn't it possible to create 2 versions of your xib, and depending on the target, compile on or the other? This would be a bit more work to maintain, but if your UI is pretty stable, this should be the easiest way.
Or you could add your "10.7 specific" UI component(s) programmatically instead of using the IB. If you just have one or a few popovers, it shouldn't be to difficult to do, and the proprocessor guards would work fine.

Canonical method of measuring iOS app startup performance?

I've been asked to reduce the startup time of an iOS application. I am very familiar with the platform/tools in general but I haven't focussed upon application startup time before. I'm wondering if there are known patterns for attacking this problem?
I realize that I can simply measure the time it takes to go from main() through the completion of application:didFinishLaunchingWithOptions: (which includes any background loading tasks), but again, I am hoping there might be a more standardized way to do this.
Any suggestions would be greatly appreciated!
-M
from WWDC 2012 session 235
set the start point at the first line of code in main.m
#import <UIKit/UIKit.h>
CFAbsoluteTime StartTime;
int main(int argc, char *argv[])
{
StartTime = CFAbsoluteTimeGetCurrent();
#autoreleasepool {
...
set the end point somewhere in AppDelegate's application:didFinishLaunchingWithOptions:
extern CFAbsoluteTime StartTime;
...
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"Launched in %f sec", CFAbsoluteTimeGetCurrent() - StartTime);
});
Your method sounds like the correct one (I recommend using CFAbsoluteTime for your measurements).
One thing which may help you reduce the launch time is to avoid having View Controllers loaded from nibs on application launch. If I am not mistaken this forces them to be loaded into memory even before your app launches. Instead, alloc and init your view controllers dynamically when you need them. Note that you can still have the Views you'd like to be loaded by the view controllers stored in Nibs, you don't have to stop using IB. Just don't use IB to set static outlets for your app delegate.