Saturday, February 9, 2013

Getting Apple's Linker to Cooperate

If you came to this entry from a Google search for "cocos2d archive crash doesNotRecognizeSelector", you've come to the right place!  I've just spent the past 2 hours figuring out why my iPad game ran fine for me, but was rejected by the app store due to a crash.

Lesson one: Test your app in Release mode!

Building in Release mode as opposed to Debug mode causes more compiler optimizations to occur, and can reveal unexpected and hard to track down bugs.  You can save yourself alot of trouble by detecting these during your development, before you submit your freshly minted app for approval.

At first I was puzzled by the rejection, since I could not duplicate the error when I clicked the Proceed button.  After some research, I realized I had to put an archived build onto my iPad using iTunes to reproduce the issue.  I did so, and sure enough, a crash after pressing the Proceed button!  I've since learned that just running the app from within Xcode is good enough, as long as you target your Scheme to run in Release instead of Debug mode.

Look at the crash log above.  So, why is the code apparently calling a Selector that it doesn't recognize?

I finally tracked this down to the Linker eliminating the CCGLView class from the build, because it incorrectly thought it wasn't being referenced.  This caused any reference to methods called on CCGLView to throw an exception, doesNotRecognizeSelector.  I'm not completely clear why the Linker came to this conclusion, but I was able to coerce the Linker to include the class by adding one line of code at the start of the CCTextureCache.m method:

[CCGLView class];

This line was enough to convince the Linker to include the class, and the crash no longer occurs in Release mode, and not even in an archived build that I copied to the iPad.

Time to resubmit to the app store!

No comments:

Post a Comment