Difficulties getting iOS 5 app running on iOS 4 - iphone

I have an iPhone app that with deployment target 4.0 and base sdk 5.0. The app runs fine on an iOS 5 simulator but when I stat the 4.3 simulator the app chrashes and I get this:
dyld: lazy symbol binding failed: Symbol not found:
_objc_retainAutoreleasedReturnValue Referenced from: /Users/joakim/Library/Application Support/iPhone
Simulator/4.3.2/Applications/F6CE76EA-DA7E-4BAC-A3AC-3CE2B51C0CD9/PingPalARC.app/PingPalARC
Expected in:
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk/System/Library/Frameworks/Foundation.framework/Foundation
dyld: Symbol not found: _objc_retainAutoreleasedReturnValue
Referenced from: /Users/joakim/Library/Application Support/iPhone
Simulator/4.3.2/Applications/F6CE76EA-DA7E-4BAC-A3AC-3CE2B51C0CD9/PingPalARC.app/PingPalARC
Expected in:
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk/System/Library/Frameworks/Foundation.framework/Foundation
sharedlibrary apply-load-rules all (gdb)
The project does not use ARC by default, however there are a few classes for with i have turned on ARC with the -fobjc-arc flag under compile sources
I do not use any weak references and I do not use storyboards, so I can not see why my app should not work on iOS 4.x. Can anyone tell me what I have missed in order for my app to work on both iOS 4 and 5.
Added Frameworks:
System Configuration
Map Kit
CFNetwok
Core Location

You are using ARC, which is not built in to iOS 4. Did you set your deployment target to 4, so the arclite library is included for you? https://devforums.apple.com/message/588316
(Ah, it sounds like you did, but aren't telling the IDE that you are using ARC. So you will have to include it yourself.)

Not really an answer, but some more information in case it helps someone more knowledgable than me...
objc_retainAutoreleasedReturnValue(obj) is new to iOS 5 and does pretty much what the name says. Conceptually, if the nominated object is in the autorelease pool then it's taken out of there, implicitly retaining it, and a suitable release is added at a later point. So it's a way of avoiding the memory bottleneck problem that can occur when conceptually temporary objects pile up in the autorelease pool. So it's an optimisation, not a new piece of behaviour.
The ARC compiler will have inserted that in one of your ARC files where some method receives an autoreleased object. As you say, it's unrelated to both weak references and storyboards and is logically something you could simply not do in order to retain iOS 4 compatibility.
Having said all that, I'm not completely confident of a workaround other than the obvious but probably very hard to stomach — modify your ARC classes so that they never receive autoreleased objects or switch off ARC entirely. Apple don't allow dynamically linked libraries to be deployed so I can't think of a safe way to offer an objc_retainAutoreleasedReturnValue alternative for iOS 4 devices.

Add all the temporary variable declarations inside autoreleasepool block inside the function.

Related

Can't compile code containing iOS 5 method when setting lower deployment target

Not true for all new iOS 5 methods but I've found out that calling UINavigationBar's setBackgroundImage:forBarMetrics: method will trigger an 'instance method not found' warning if the deployment target is under 5.0. This is even though I am linking with the SDK 5.0.
More importantly the enum UIBarMetrics used as a parameter there is reported as an 'undeclared identifier' and this will trigger a compiler error.
Any idea why this is so? I realized the code will not work if the deployment target is under 5.0 but I'm checking if UINavigationBar responds to that selector at run time, so everything should be ok. I don't understand the compiler error though.
EDIT:
This only happens when compiling for a device, and when a device is actually plugged in (the device I've tested with runs iOS 5.0.1).
Well, I figured out the mystery. I manage to fix the problem by deleting SDK 4.3 (I had that one copied over from Xcode 3 since it doesn't come by default with the latest Xcode+SDK package and I was using it for another legacy project).
I still can't explain why having both SDKs caused the error since I was clearly compiling with the latest SDK.

apps works fine in iOS 4.3 but crashing in iOS 5

My apps start crashing after upgrading to iOS 5 with Xcode 4.2. Otherwise the same source is validated working in iOS 4.3. I am quite clueless about what might have occurred since the backtrace did not reveal much info. Here is what I can say about the behavior of the crash: -
The backtrace revealed the last attempt to free memory resource from the automatic pool which triggers the EXC_BAD_ACCESS signal.
The problem disappeared after setting the env. variable NSZombieEnabled. This is all very sad, I was hoping that NSZombieEnabled could reveal the attempt to release deallocated instance.
When migrating source to iOS 5, do I need to take extra precaution, having to make modification to my Obj-C source to suit iOS 5? At this moment I have not make any enhancement to the source to take additional features in iOS 5.
I read something about ARC, do you think ARC may be able to cause new crashes never seen in prior versions of iOS?
Any tips and advice about migrating existing source to iOS5 is appreciated.
As it turned out the UITableViewCell* as returned by tableView:cellForRowAtIndexPath: needs to be retained manually (nope I did turn on the ARC).
I am loading custom nib files manually and followed Apple's sample code religiously at this link
I still do not understand why I need to retain it. I have several other tables in my apps which do not retain the returned cell and yet functioning as usual in iOS5.

App crashes on Apple LLVM 3.0 but works OK on LLVM GCC 4.2

I have a very strange crash when using the Apple LLVM 3.0 compiler.
So there is some code, that uses Assimp to load assets and create the scene (I've excluded all my code and even then it crashes):
aiScene* ai_scene = const_cast<aiScene*>(aiImportFileFromMemory(fileBuf, fInfo.uncompressed_size, aiProcessPreset_TargetRealtime_MaxQuality, NULL));
delete ai_scene;
Here is the screenshot of the stack trace for GCC:
And here is for LLVM:
In LLVM version destructor is called twice (and probably that's why I've got a crash).
I should also mention that all destructor code is located in header file and crashes only on device (tested on iPod 4 and iPad 2).
Is it a bug in LLVM compiler (probably in generation of arm assembly) or did I miss something?
Edit:
in case someone has similar problem use aiReleaseImport(scene) instead of delete scene;
You are not supposed to delete that pointer at all. Read the documentation. It clearly states that you should not attempt to free it in any way.
If the call succeeds, the contents of the file are returned as a
pointer to an aiScene object. The returned data is intended to be
read-only, the importer keeps ownership of the data and will destroy
it upon destruction. If the import fails, NULL is returned. A
human-readable error description can be retrieved by calling
aiGetErrorString().
And in addition, the documentation explicitly states that it's read-only, so do not const_cast the const away.
I had a similar problem earlier, and it was quite rare because I go no responses (other than my own) to that problem AppStore build crashes on launch on iPhone 3g and iPod Touch
It'd crash only on iPhone 3g, and on an old iPod touch.

XCode building: identical configurations behave differently

I have a superweird problem:
I get a crash (EXC_BAD_ACCESS) when running my app with Release as active configuration on my 3.1.3 iPhone 3G. (works well in debug configuration or in simulator , works perfectly on device running iOS4).
My first guess was one setting in the Release configuration was erroneous/missing. In order to test it I just made a duplicate of my debug configuration and surprisingly I get the same error (although configuration is just a copy of the one working).
I don't understand why, with configurations that are supposed to be the same, one is working and not the other one.
If someone want to enlighten me, I am banging my head against the wall.
Thank you
NOTE: base SDK is 4.0 and deployment target is 3.0
Perhaps you have an unassigned local variable. Object-C follows how C does this. So in a release version you cannot assume that any local variable is initialised to 0 whilst in debug you can (in this case I would guess a pointer).
EDIT:
Pass -Wuninitialized to the compiler (or better -Wall) for the compiler to warn on these Apple gcc man page Note only works if optimizer is on.
You should check for memory leaks and handling of memory warnings. The amount of memory is probably the biggest difference between the environments you quote.
In another scenario I once found out that the simulator was faster, and therefore a certain race condition didn't show up, which did show up on the device. That's the second difference in the environments you quote: speed.
Try to pinpoint your crash and investigate from there. NSLog all didReceiveMemoryWarnings. Look for places where you made assumptions, i.e. about static information.
I fixed the problem.
It was three20 library fault. I had updated to the master branch that support iOS 4 but unfortunately this breaks support for 3.1.3. (thing that is not documented apparently)
Anyway I found this post that helped me to spot the problem. I just had to apply this patch and then I was able to run my project on 3.1.3 devices and iOS4 ones
Weird thing: why was it crashing when I was initializing a UIActionSheet (on a line of code not related at all with the Three20 lib)?
Thank you for your help.

Permanently ignoring warnings

I have a project that compiles with some warnings. It's an iPhone project that uses some methods on NSDate, that are seemingly not the headers of the iPhone SDK, but work flawlessly none the less. When I call these methods I get warnings like:
NSDate warnings http://beautifulpixel.com/assets/NSDate_Warnings-20090215-235727.png
So how do I silence the warnings permanently, in order to tell XCode "it's OK, really."
Or how do I correct the warnings? This code works great on the device and Apple has already approved an app that uses these same methods, so surely I can get XCode to understand that the methods really are there.
I would very strongly advise you to not use these methods. Just because they are declared in Mac OS X's Foundation framework, does not stop them being private API on the iPhone. Apple would be well within their rights to discontinue your app from the store. Likewise, there's nothing to stop Apple tidying up Foundation a bit for an iPhone OS 2.2.2 or later release and removing those two methods, thereby breaking your app.
You can write a short interface extension early in you .m file to suppress these warnings
Example:
#interface NSDate (SuppressSomWarnings)
- (void)dateWithNaturalLanguageString:(NSString*)_str;
#end
It's strange, I do not get any warning when I type the same two lines... Did you correctly import the headers and frameworks into your project?
I see that they are defined in NSCalendateDate.h, which is in Foundation.framework.
Failing that, you can try and include the interface definitions directly into your code, e.g., at the top of your .m file, to see if that gets rid of the warnings. (See epatel's answer that came while I was writing this!)
Do you have the correct SDK configured?
You might be liking against the newest version, but using old header files.
Your code may work in the simulator but does it work on the phone?
The simulator uses the OS X Foundation framework which is a superset of what is available on the iPhone.