ERROR objc_retainedObject() unavailable - objective-c

when i'm trying to build my project I have a new error where objc_retainedObject() is used.
I have the error message objc_retianedObject is unavailable: use CFBridgingRelease() or a (__bridge_transfer id) cast instead.
I replaced the usages of objc_retainedObject() by CFBridgingRelease and there are no longer errors and I can run the app, but when the app is going to display my QRCode-scanning view, it crashed without messages.
It is the same when I put #define objc_retainedObject(o) ((__bridge_transfer id)(objc_objectptr_t)(o)) which was supposed to be a solution.
I believe that it is an XCode configuration or a missing library problem. Any ideas?

Do not recreate objc_retainedObject. It was removed on purpose. CFBridgingRelease and CFBridgingRetain are the correct tools for moving CF objects into ARC. (__bridge is the tool for dealing with CF objects that you don't need to transfer to ARC because you aren't storing them.)
If your program is crashing, you're probably managing memory incorrectly. It is likely that objc_retainedObject was incorrect (even if you happened to get away with it). See when should you use __bridge vs. CFBridgingRelease/CFBridgingRetain? for correct memory management when transferring CF objects to ARC.
Without knowing more about the code, I can't guess exactly where you've made a mistake, but you probably are calling CFBridgingRelease on an object that you didn't acquire via the Create Rule. You don't just throw CFBridgingRelease on every CF object you encounter. You need to make sure you're balancing an existing retain.

Related

Memory Leaks when Working with Address Book Contacts in iOS6

I'm using ARC, and my application compiles and works without crashing. However, when I run an Analyze build, I am seeing these warnings. I come from PHP and JavaScript so naturally I have no idea what to do to fix this stuff. Can anyone help me out?
ARC needs some help when dealing with Core Foundation. Try this:
NSArray *linkedPeople = (__bridge_transfer NSArray *)ABPersonCopyArrayOfAllLinkedPeople(person);
and
NSDictionary *personDictionary = (__bridge_transfer NSDictionary *)(ABMultiValueCopyValueAtIndex(addressFromPerson, 0));
__bridge_transfer tells ARC that a non-Objective-C (i.e., Core Foundation) pointer is being moved to an Objective-C pointer, and it allows ARC to take ownership of the object for memory management purposes. CF functions with the word "copy" in them produce an object reference with a +1 reference count. If you don't explicitly call CFRelease() on the object later, then it will leak. Using __bridge_transfer, however, lets ARC do this for you.
(Note: I didn't test this, but I believe those are the issues that the static analyzer is complaining about.)
Yes, you can use:
NSArray *linkedPeople = (__bridge_transfer NSArray *)ABPersonCopyArrayOfAllLinkedPeople(person);
But Apple now recommends using:
NSArray *linkedPeople = CFBridgingRelease(ABPersonCopyArrayOfAllLinkedPeople(person));
It does the same thing, but Apple recommends you use the latter.
See WWDC 2012 session 405, 37:33 into the presentation.
So! Even though you're using Automatic Reference Counting (ARC), it's still a good idea to read up on Objective-C Memory Management:
http://longweekendmobile.com/2011/09/07/objc-automatic-reference-counting-in-xcode-explained/
But, for your specific problem:
Generally, when you see a C method in the Apple frameworks that has the word Copy in it, you're taking ownership of that Core Foundation type and you need to release it. When you want to release that type, just use:
CFRelease(addressFromPerson)
That's the first issue. Your screenshot cuts off the second error so I'm only speculating, but I think you also need to release your NSDictionary *personDictionary. Similarly:
CFRelease(personDictionary)
Note that you also need to manage the memory for linkedPeople
Normally ARC will take care of memory management for you, but when working with Core Foundation types, you still need to clean up after yourself.
I would strongly recommend you check out these great resources on memory management with ARC, particularly when dealing with CF types and toll-free bridging:
http://www.joergjacobsen.com/blog/2011/10/05/managing-toll-free-bridging-in-an-arced-environment/
http://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html

autorelease not allowing to compile code

I am trying to convert an old code to an ARC code.
However, i am getting a build error at the following line
[[token retain] autorelease];
I get 3 errors in the following order:
-'autorelease' is unavailable: not available in automatic reference counting mode
-[rewriter] it is not safe to remove an unused 'autorelease' message; its receiver may be destroyed immediately
-ARC forbids explicit message send of 'autorelease'
If i remove this particular line, then the code compiles correctly
If that is all that is on the line, you can probably just remove it. That code claims a reference to the object but also says you don't want to worry about releasing later, but with ARC you don't have to worry about it.
I am guessing that Xcode did not get rid of it automatically because of lack of context. If it had been in a more common location, such as in a return statement, it would be obvious what the intent was. When it is all by itself, it could be, but probably is not, something more complicated.
ARC manages your memory for you, so you don't need to call "autorelease", "release", "retain" etc. With ARC the compiler retain and release objects as necessary for you so you don't have to explicitly make these calls. If you want to manually manage your memory disable ARC, or you can use the compiler flag "-fno-objc-arc" to disable ARC on a specific class.
ARC means you don't have to use release, retain or those other pesky memory management things. ARC add them all for you automatically when you compile the app. Read more here
If you have old code where it would not be the best solution to remove all the memory management calls, then check this answer to disable ARC for particular files

converted my app to ARC but only 1 target shows ARC setting as YES?

I believe I successfully converted by app to ARC using the 'Refactor -> Convert to Objective-C ARC' tool but only one of my project targets has the setting:
And if I create anything using IB it is still generating retain / release / dealloc code?
Also I now have crashes I did not before because of memory use, so I am wondering if my project is in a half converted state that is causing me random memory issues.
How do I get these other targets to use ARC - or make sure they are using ARC?
Manually change the flags to say YES. Also want to check and make sure that none of the files have the compiler flag "-fno-objc-arc" set. (I've run into projects that were half converted this way.)
If you're still running into memory issues, run the Leaks Instrument. Even with ARC, you can still have memory leaks like retain cycles where parent-child relationships retain each other. In such a case, you need to use weak pointers.

Track all Objective-C's alloc/allocWithZone/dealloc

Sorry for long description, however the questions aren't so easy...
My project written without GC. Recently I found a memory leak that I can't find. I did use new Xcode Analyzer without a result. I did read my code line by line and verified all alloc/release/copy/autorelease/mutableCopy/retain and pools... - still nothing.
Preamble: Standard Instruments and Omni Leak Checker don't work for me by some reason (Omin Tool rejects my app, Instruments.app (Leaks) eats too many memory and CPU so I have no chance to use it).
So I wanna write and use my own code to hook & track "all" alloc/allocWithZone:/dealloc messages statistics to write some simple own leaks checking library (the main goal is only to mark objects' class names with possible leaks).
The main hooking technique that I use:
Method originalAllocWithZone = class_getClassMethod([NSObject class],#selector(allocWithZone:));
if (originalAllocWithZone)
{
imp_azo = (t_impAZOriginal)method_getImplementation(originalAllocWithZone);
if (imp_azo)
{
Method hookedAllocWithZone = class_getClassMethod([NSObject class],#selector(hookedAllocWithZone:));
if (hookedAllocWithZone)
{
method_setImplementation(originalAllocWithZone,method_getImplementation(hookedAllocWithZone));
fprintf(stderr,"Leaks Hook: allocWithZone: ; Installed\n");
}
}
}
code like this for hook the alloc method, and dealloc as NSObject category method.
I save IMP for previous methods implementation then register & calculate all alloc/allocWithZone: calls as increment (+1) stat-array NSInteger values, and dealloc calls as decrement (-1).
As end point I call previous implementation and return value.
In concept all works just fine.
If it needs, I can even detect when class are part of class cluster (like NSString, NSPathStore2; NSDate, __NSCFDate)... via some normalize-function (but it doesn't matter for the issues described bellow).
However this technique has some issues:
Not all classes can be caught, for
example, [NSDate date] doesn't catch
in alloc/allocWithZone: at all, however, I can see alloc call in GDB
Since I'm trying to use auto singleton detection technique (based on retainCount readind) to auto exclude some objects from final statistics, NSLocale creation freezes on pre-init stage when starting of full Cocoa application (actually, even simple Objective-C command line utility with the Foundation framework included has some additional initialization before main()) - by GDB there is allocWithZone: calls one after other,....
Full Concept-Project draft sources uploaded here: http://unclemif.com/external/DILeak.zip (3.5 Kb)
Run make from Terminal.app to compile it, run ./concept to show it in action.
The 1st Question: Why I can't catch all object allocations by hooking alloc & allocWithZone: methods?
The 2nd Question: Why hooked allocWithZone: freezes in CFGetRetainCount (or [inst retainCount]) for some classes...
Holy re-inventing the wheel, batman!
You are making this way harder than it needs to be. There is absolutely no need whatsoever to roll your own object tracking tools (though it is an interesting mental exercise).
Because you are using GC, the tools for tracking allocations and identifying leaks are all very mature.
Under GC, a leak will take one of two forms; either there will be a strong reference to the object that should long ago been destroyed or the object has been CFRetain'd without a balancing CFRelease.
The collector is quite adept at figuring out why any given object is remaining beyond its welcome.
Thus, you need to find some set of objects that are sticking around too long. Any object will do. Once you have the address of said object, you can use the Object Graph instrument in Instruments to figure out why it is sticking around; figure out what is still referring to it or where it was retained.
Or, from gdb, use info gc-roots 0xaddr to find all of the various things that are rooting the object. If you turn on malloc history (see the malloc man page), you can get the allocation histories of the objects that are holding the reference.
Oh, without GC, huh...
You are still left with a plethora of tools and no need to re-invent the wheel.
The leaks command line tool will often give you some good clues. Turn on MallocStackLoggingNoCompact to be able to use malloc_history (another command line tool).
Or use the ObjectAlloc instrument.
In any case, you need to identify an object or two that is being leaked. With that, you can figure out what is hanging on to it. In non-GC, that is entirely a case of figuring out why it there is a retain not balanced by a release.
Even without the Leaks instrument, Instruments can still help you.
Start with the Leaks template, then delete the Leaks instrument from it (since you say it uses too much memory). ObjectAlloc alone will tell you all of your objects' allocations and deallocations, and (with an option turned on, which it is by default in the Leaks template) all of their retentions and releases as well.
You can set the ObjectAlloc instrument to only show you objects that still exist; if you bring the application to the point where no objects (or no objects of a certain class) should exist, and such objects do still exist, then you have a leak. You can then drill down to find the cause of the leak.
This video may help.
Start from the Xcode templates. Don't try to roll your own main() routine for a cocoa app until you know what you're doing.

Avoiding, finding and removing memory leaks in Cocoa

Memory (and resource) leaks happen. How do you make sure they don't?
What tips & techniques would you suggest to help avoid creating memory leaks in first place?
Once you have an application that is leaking how do you track down the source of leaks?
(Oh and please avoid the "just use GC" answer. Until the iPhone supports GC this isn't a valid answer, and even then - it is possible to leak resources and memory on GC)
In XCode 4.5, use the built in Static Analyzer.
In versions of XCode prior to 3.3, you might have to download the static analyzer. These links show you how:
Use the LLVM/Clang Static Analyzer
To avoid creating memory leaks in the first place, use the Clang Static Analyzer to -- unsurprisingly -- analyse your C and Objective-C code (no C++ yet) on Mac OS X 10.5. It's trivial to install and use:
Download the latest version from this page.
From the command-line, cd to your project directory.
Execute scan-build -k -V xcodebuild.
(There are some additional constraints etc., in particular you should analyze a project in its "Debug" configuration -- see http://clang.llvm.org/StaticAnalysisUsage.html for details -- the but that's more-or-less what it boils down to.)
The analyser then produces a set of web pages for you that shows likely memory management and other basic problems that the compiler is unable to detect.
If your project does not target Mac OS X desktop, there are a couple of other details:
Set the Base SDK for All Configurations to an SDK that uses the Mac OS X desktop frameworks...
Set the Command Line Build to use the Debug configuration.
(This is largely the same answer as to this question.)
Don't overthink memory management
For some reason, many developers (especially early on) make memory management more difficult for themselves than it ever need be, frequently by overthinking the problem or imagining it to be more complicated than it is.
The fundamental rules are very simple. You should concentrate just on following those. Don't worry about what other objects might do, or what the retain count is of your object. Trust that everyone else is abiding by the same contract and it will all Just Work.
In particular, I'll reiterate the point about not worrying about the retain count of your objects. The retain count itself may be misleading for various reasons. If you find yourself logging the retain count of an object, you're almost certainly heading down the wrong path. Step back and ask yourself, are you following the fundamental rules?
Always use accessor methods; declare accessors using properties
You make life much simpler for yourself if you always use accessor methods to assign values to instance variables (except in init* and dealloc methods). Apart from ensuring that any side-effects (such as KVO change notifications) are properly triggered, it makes it much less likely that you'll suffer a copy-and-paste or some other logic error than if you sprinkle your code with retains and releases.
When declaring accessors, you should always use the Objective-C 2 properties feature. The property declarations make the memory management semantics of the accessors explicit. They also provide an easy way for you to cross-check with your dealloc method to make sure that you have released all the properties you declared as retain or copy.
The Instruments Leaks tool is pretty good at finding a certain class of memory leak. Just use "Start with Performance Tool" / "Leaks" menu item to automatically run your application through this tool. Works for Mac OS X and iPhone (simulator or device).
The Leaks tool helps you find sources of leaks, but doesn't help so much tracking down the where the leaked memory is being retained.
Follow the rules for retaining and releasing (or use Garbage Collection). They're summarized here.
Use Instruments to track down leaks. You can run an application under Instruments by using Build > Start With Performance Tool in Xcode.
I remember using a tool by Omni a while back when I was trying to track down some memory leaks that would show all retain/release/autorelease calls on an object. I think it showed stack traces for the allocation as well as all retains and releases on the object.
http://www.omnigroup.com/developer/omniobjectmeter/
First of all, it's vitally important that your use of [ ] and { } brackets and braces match the universal standard. OK, just kiddin'.
When looking at leaks, you can assume that the leak is due to a problem in your code but that's not 100% of the fault. In some cases, there may be something happening in Apple's (gasp!) code that is at fault. And it may be something that's hard to find, because it doesn't show up as cocoa objects being allocated. I've reported leak bugs to Apple in the past.
Leaks are sometimes hard to find because the clues you find (e.g. hundreds of strings leaked) may happen not because those objects directly responsible for the strings are leaking, but because something is leaking that object. Often you have to dig through the leaves and branches of a leaking 'tree' in order to find the 'root' of the problem.
Prevention: One of my main rules is to really, really, really avoid ever allocating an object without just autoreleasing it right there on the spot. Anywhere that you alloc/init an object and then release it later on down in the block of code is an opportunity for you to make a mistake. Either you forget to release it, or you throw an exception so that the release never gets called, or you put a 'return' statement for early exit somewhere in the method (something I try to avoid also).
You can build the beta port of Valgrind from here: http://www.sealiesoftware.com/valgrind/
It's far more useful than any static analysis, but doesn't have any special Cocoa support yet that I know of.
Obviously you need to understand the basic memory management concepts to begin with. But in terms of chasing down leaks, I highly recommend reading this tutorial on using the Leaks mode in Instruments.