today i tried to run my first iPhone app(the app is assignment in Stanford course).
in the assignment i ask to defining and instantiating class in interface builder, i defined the class run the simulator and everything work just fine. when i tried to connect the class(and the object) to the UI and then run the simulator xcode was crashed and show this message:
Thread 1:signal sigABRT
when i remove the connection between the class to the UI(i remove the connection between the outlets and the label in the app view) everything is again work fine.
i tried to understand where the problem came from with breakpoints and the crash is in this line of code(in the main file):
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
pls help me, it's make me crazy.
Xcode 4.x is not very good at telling you where the real error is and shows that line in main.m instead. Try replacing it with code that shows you more information:
#try {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
#catch (NSException *exception) {
NSLog(#"Exception %#\n%#", [exception description], [exception callStackSymbols]);
}
Related
I need some help in Xcode. I am getting the error Thread 1: SIGABRT and it is pointing to the main.m file. I set up the exception breakpoint and it still stops in the main.m file.
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import "AppDelegate.h"
int main(int argc, char *argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
That is the code that I have in my main.m file. Can someone please help me with this error.
The full error is:
2013-09-07 23:41:05.440 save the jewel 5[86090:c07] -[game pause:]: unrecognized selector sent to instance 0x845ece0
2013-09-07 23:41:09.460 save the jewel 5[86090:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[game pause:]: unrecognized selector sent to instance 0x845ece0'
*** First throw call stack:
(0x1693012 0x13a0e7e 0x171e4bd 0x1682bbc 0x168294e 0x13b4705 0x2e82c0 0x2e8258 0x3a9021 0x3a957f 0x3a86e8 0x317cef 0x317f02 0x2f5d4a 0x2e7698 0x26f5df9 0x26f5ad0 0x1608bf5 0x1608962 0x1639bb6 0x1638f44 0x1638e1b 0x26f47e3 0x26f4668 0x2e4ffc 0x23c2 0x22f5)
libc++abi.dylib: terminate called throwing an exception
In my game.m file I have:
-(void)pauseLayer:(CALayer*)layer{
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
layer.speed = 0.0;
layer.timeOffset = pausedTime;
}
-(void)resumeLayer:(CALayer*)layer{
CFTimeInterval pausedTime = [layer timeOffset];
layer.speed = 1.0;
layer.timeOffset = 0.0;
layer.beginTime = 0.0;
CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
layer.beginTime = timeSincePause;
}
- (IBAction)pause:(id)sender {
[self pauseLayer:self.view.layer];
}
- (IBAction)resume:(id)sender {
[self resumeLayer:self.view.layer];
}
In my game.h file I have:
- (IBAction)pause:(id)sender;
- (IBAction)resume:(id)sender;
-(void)pauseLayer:(CALayer*)layer;
-(void)resumeLayer:(CALayer*)layer;
I need some help.
-[game pause:]: unrecognized selector sent to instance 0x845ece0
This means that you have an instance of the game class (which, btw, that class should be Game, not game, classes are capitalized) and something is calling the method pause: on that class, but there is no pause: method.
Given that the class is called Game (fixed) and pausing seems like a reasonable thing to do to a game, it is unlikely that this is an over-release problem. pause: seems like it is something that you might have a button hooked up to in interface builder.
Did you, perchance, rename the pause: method to something else (pauseGame:?) and not fix the connection in IB?
And that pause: implementation is inside the #implementation Game scope? If so, trying cleaning the project and rebuilding as there may be a dependency issue. If not, then that is your problem.
If the build from clean thing doesn't work, then there is some detail missing. Since building from clean didn't work, you'll have to post more details. Show the declaration of the class, at least.
Does anybody have an experiencing with refactoring a project built with Xcode 4.3 down to build with 4.1? I get a black screen (not a crash) on load.
If I set a breakpoint on exception, I get an assembly breakpoint.
That leads me to believe that window or something is not getting loaded. I'm not using ARC, and the interface is built with IB. I'm using straight llvm. I have a feeling my problem is in main.
Okay, I got it.
4.1 doesn't like the way that a Universal app is built, apparently. So, here's what I did.
replace in main
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
with this
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
[pool release];
return retVal;
The important bit is to send the appDelegate to the 4th arg of UIApplicationMain. If it's nil, it'll look for the appDelegate in the main nib. Hope this helps someone.
I would suggest creating a blank project in XCode 4.1 and 4.3 and then compare the Info.plist file and the content of .xcodeproj folder. Your problem may be actually related to specifying the main window or some of the defaults values (that could have been set in the new project and don't work properly in the old one).
in xcode4.2 the SIGABRT always disapear on main.m. I can't get where real it is.
on this line:
int retVal = UIApplicationMain(argc, argv, nil, #"AppDelegate");
on xcode3.2 it work well.
try adding a objc_exception_throw as symbolic breakpoint in your Debug scheme - this will stop debugger just in the place where exception is thrown
I use HessianKit to communicate with server. In the situation of network or server down Hessian will throw exception, so I put every Hessian call in a #try ... #catch block. Everything worked fine until I upgraded Xcode from 3.2.2 to 3.2.3. I wrote the some testing code and found under Xcode 3.2.3, catch exception would be failed if the exception was thrown from a proxy object.
MyProxy.h:
#interface MyProxy : NSProxy {
}
#end
MyProxy.m:
#implementation MyProxy
- (id)init {
return self;
}
- (void)forwardInvocation:(NSInvocation *)invocation {
NSLog(#"Call method %#", NSStringFromSelector([invocation selector]));
[NSException raise:#"MyException" format:#"this is an exception"];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
.....
}
#end
Code using MyProxy:
#try {
MyProxy *p = [[MyProxy alloc] init];
[p doSomething];
[p release];
}
#catch (NSException * e) {
NSLog(#"%#", e);
}
When these code build under xcode 3.2.2, the exception can be catched correctly. But under xcode 3.2.3, the program terminated after output following on the console:
2010-09-08 21:09:29.877 BriefCase[34651:40b] Call method doSomgthing
2010-09-08 21:09:29.879 BriefCase[34651:40b] *** Terminating app due to uncaught exception 'MyException', reason: 'this is an exception'
2010-09-08 21:09:29.880 BriefCase[34651:40b] Stack: (
45955152,
47113004,
45692683,
45692522,
151932,
45426420,
45423090,
9352,
4417860,
4421967,
4447550,
4429047,
4461016,
53399932,
45234332,
45230248,
4420129,
4453234,
8812,
8666
)
terminate called after throwing an instance of 'NSException'
Program received signal: “SIGABRT”.
What can I do?
I filed a bug with Apple, and the reply is:
It has been determined that this is a known issue, which is currently being investigated by engineering. This issue has been filed in our bug database under the original Bug ID# 7995323.
Maybe your project/target/executable settings have been messed up?
Is the "Enable Objective-C Exceptions" box ticked for your configuration/target/etc?
If it is, maybe you should file a bug with Apple here.
Consider the following main() method which you would find most iPhone applications:
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
In every iPhone app that I've run in Simulator with these (including several sample projects provided by Apple), the thread never exits UIApplicationMain() and any remaining code in main() is never executed. Is this expected behavior?
I have verified that statements after UIApplicationMain() never run by stepping through the code with a debugger. When the user stops an application (by hitting the "Home" button, for example), the resulting stack trace shows that [UIApplication _terminateWithStatus:] is eventually called. This function calls your application delegate's applicationWillTerminate: method. Once that finishes, [UIApplication _terminateWithStatus:] seems to kill/exit the thread.
Can someone confirm that this is how main() is supposed to work, or at least confirm the same behavior on their machine?
The original question was: "Why doesn’t an iPhone app’s main() function ever get a chance to finish?"
Short Answer: Because UIApplicationMain() is coded such that it never returns.
After doing several tests in Simulator and on the device, and asking another developer to do the same tests, I have confirmed that UIApplicationMain never returns. When the user terminates an application normally by hitting the Home button, The program ultimately terminates inside an unpublished UIApplication method called _terminateWithStatus. This method calls exit(0).
This behavior matches that of the NSApplicationMain function (which is AppKit/Cocoa version of the UIApplicationMain function). The documentation for NSApplicationMain() clearly states that it will never return.
I have submitted a bug (6600198) to Apple requesting that the official documentation (and Xcode template for main.m) be corrected to state that UIApplicationMain() never returns. While this is not a functional problem, the current template and docs are misleading.
Thanks to everyone for all the input and brainstorming!
Try:
int main(int argc, char *argv[])
{
NSLog(#"Step 0");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSLog(#"Step 1");
int retVal = UIApplicationMain(argc, argv, nil, nil);
NSLog(#"Step 2");
[pool release];
NSLog(#"Step 3");
return retVal;
}
It may be that the release of the pool is preventing further logging in which case you'd get step 2 but not step 3.
If step 2 isn't being printed, then it's almost certainly something wrong with UIApplicationMain - there's a chance that it doesn't return so put NSLog statements (step 1.1, Step 1.2, ...) at various points within it and run to find the last message logged.
Keep drilling down (Step 1.7.1, 1.7.2, .... 1.7.6.3.2, ...) - eventually, you'll track down the exact line (however deep in the call hierarchy) when the log messages stop being logged and that line will be your culprit (either "turning off" logging or exiting without returning normally).
One further snippet I found on the web:
=====
When you use this line:
int retVal = UIApplicationMain(argc, argv, #"MyApp", #"MyApp");
The first MyApp is your main app delegate class. The second is the class to where SpringBoard sends touch notifications.
Also, if you are using the SDK, and have a main nib defined in the Info.plist, then you can leave the call as:
int retVal = UIApplicationMain(argc, argv, nil, nil);
as all that will be covered when you create your xibs.
=====
Now I don't know enough about iPhone development (specifically xibs) to know what that last bit even means (or if you've set it up correctly) but it sounds like another phase of compilation.
However, my first thought from reading that is that Springboard will call your delegate class when the buttons are pressed to ask you to do something (like shut down gracefully). If it can't ask you (i.e., no delegate), it's probably within its rights to shut you down as it sees fit, such as with [UIApplication _terminateWithStatus:].
In the Windows world, you would probably send off a quit message to the main window but, as I say, iPhone development may be different.
Still, it's an avenue to investigate. I'd be interested in seeing what calls were made to a delegate if you provided one. The code included with the snippet above had this:
#implementation MyApp
- (void) applicationDidFinishLaunching:(id)unused {
rect = [ UIHardware fullScreenApplicationContentRect ];
rect.origin.x = 0.0f;
rect.origin.y = 0.0f;
window = [ [ UIWindow alloc ] initWithContentRect: rect ];
[ window makeKeyAndVisible ];
view = [ [ MyAppView alloc ] initWithFrame: rect ];
[ window setContentView: view ];
}
- (void) dealloc {
[ window release ];
[ view release ];
[ super dealloc ];
}
So maybe a delegate with dealloc() is the secret to getting it to exit back to main(). Why don't you give that a shot? It may get you closer to your goal even if it doesn't solve the core problem.
After [pool release] there is nothing to log to?
trying using fprintf and see what happens
int main(int argc, char *argv[])
{
/*
...
same as above
...
*/
[pool release];
char file_name = "/tmp/log"
FILE *file = fopen(file_name, "w");
fprintf(file_name, "END\n");
}
and tell us what happens
I also thought the easiest way to check was to set a break point right at the return
in gdb do
b main.c:x
where x is the line number of the return statement
After calling the UIApplicationMain function your application launches (establishing a runloop, etc) and all work should then be done outside the context of main (if you need it to run in main, do it before that point). When quitting an application it is generally more efficient to allow the OS to do memory cleanup.
I have that not return experience too. And have set break points to verify exactly like Clint said.
wisequark has a good point.
great topic. makes me feel more comfortable that i am not the only one who has the question.