ARC: Analyzer warnings with Objective-C code using core foundation - objective-c

Using the analyzer on some Objective-C | Cocoa / Core Foundation code, I got a few error that I can't fix because I don't understand them.
Error #1:
In an Objective-C class header, I declare this property.
#property(readwrite) CFMutableSetRef gClients;
In the body, I get the following error:
Question: Why is that a leak ? I store it in a property and dispose of it later. I thought ARC knew how to deal with CF "objects".
Error #2:
Later on, I have this error when releasing the object:
Question: How can I take those two Analyzer warnings into account in order to create a code that actually works (self.gClients lives between calls to ClientInitialize and destroyAllClients) but does not get flagged?

ARC doesn't manage CF objects without manual intervention. There is work you need to do first.
See http://www.idryman.org/blog/2012/11/22/arc-best-practices-and-pitfalls/ at "ARC and toll-free bridging". There are special casting tricks with (__bridge_transfer).

Related

ERROR objc_retainedObject() unavailable

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.

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

Memory leaks JSONKit iOS

I'm using JSONKit in my app, but when I click analyze in Xcode I get 2 issues in JSONKit.m:
Issue 1:
Issue 2:
Should I do something about this?
I would imagine that those aren't actual memory leaks. Both methods have 'Create' in their name which I think is meant to follow the Core Foundation create rule. I would guess that the analyser is just applying the Objective-C convention where only variants 'new', 'alloc', 'copy' and 'retain' are supposed to return owning references.
Those are clear C functions rather than Objective-C methods; I guess the analyser is applying Objective-C rules because Objective-C objects are being returned, albeit confusingly because the normal conventions are being deliberately ignored.

What are ARC restrictions, and how can I remove them?

I just downloaded an Xcode project, and I get all these errors about "ARC Restrictions." What are these, and how can I remove them?
There are basically two versions of memory management in objective-c. ARC and... well, "Not ARC" :-) You probably downloaded a project, which doesn't use ARC already. Simplest way of resolving your problem is to instruct the compiler to treat your sources as "Not ARC". Explained here.
And here is a good tutorial that should get you started with ARC.
ARC automatically keep track of memory release and retain so you can not release and retain any memory manually.
ARC also doesn't allow any method to be get called at compile time which prototype is not declared in interfaces.
It has also introduced new #autoreleasepool block. so it doesn't not allow older autorelease of an object automatically
However it has allowed dealloc method to be written, but it doesn't allowed [super dealloc] to be get called.
There are much more written about ARC at this blog you can checkt it here
You can covert your project to ARC using xcode in following way.
Go to Edit -> Refactor -> Convert to objective c arc.
However it has some compatibility issue with git repository so it does not convert when .git folders are there in projects. so you will have to remove it first and then convert it. check this link

Updating CoreFoundation PriorityQueue implementation to take advantage of ARC for iOS

I found an implementation of a priority queue that primarily uses CFBinaryHeap to work.
I'm currently using the -fno-objc-arc compiler flag to skip the usage of ARC while compiling these files. I attempted to update this code to take advantage of ARC, though I've run into a few snags of understanding.
Is there anyone here who has updated code similar to this for use with ARC?
How do you handle things like free(), and CFRelease()? Can we just get rid of them?
What do you do with the retain and release methods you create for CFBinaryHeapCallBacks?
Do you use __bride or __bridge_transfer to reference the const void * into Objective-C objects? Likewise should you use (__bridge_retained void *) or obj_unretainedPointer() to do the reverse?
ARC basically is a compiler technology that automatically inserts calls to -retain, -release, and -autorelease as needed. It does not remove the need for retains and releases, it just makes them automatic (in the process, optimizing out many that are not required, and playing other tricks to make various common patterns much more efficient than if you did it by hand).
ARC knows nothing about Core Foundation, nor about void* objects, malloc, free, or anything other than ObjC memory management.
This means that as long as you use Core Foundation objects, you should continue to use CFRelease. And if you malloc memory, you should continue to free it.
But.... what if you want to take memory that was created by Core Foundation and transfer it to Cocoa via a toll-free bridge? That's where __bridge* comes in. One of the best sources of information is the clang docs themselves. A great blog article is Everything you need to know about ARC. It includes many useful links to the definitive information.
But here's the short answer (from Transitioning to ARC)
NSString *c = (__bridge_transfer NSString*)my_cfref; // -1 on the CFRef
CFStringRef d = (__bridge_retained CFStringRef)my_id; // returned CFRef is +1
Using __bridge_transfer logically moves a CF object into Cocoa. Using __bridge_retained logically moves a Cocoa object into CF. You use these when you are really transferring ownership of the object. In the above example, you generally shouldn't continue using the my_ variables in my opinion. These are particularly useful in cases where you are returning the result out of the function. These should be used for their logical ownership functionality only. Don't use them as a way to "fake" a manual call to retain or release.
If you just want to have a temporary "bridged" pointer to the object so you can use it in CF or Cocoa without transferring it, then use __bridge. That's a no-op that says "don't do any memory management, just let me pretend for the moment that it's the other kind of object." If you do a lot of toll-free bridging, you'll wind up using __bridge quite a lot (making it seem like a small toll.... :D)
Here is a pure objective-c implementation of PriorityQueue, that supports ARC:
https://github.com/jessedc/JCPriorityQueue/tree/experimental/heap-queue
Is simple to implement non ARC lib into XCode project. Just open "Build Phases"(menu when click on your project target) -> "Compile Sources" and to files, which are not using ARC add by double click flag "-fno-objc-arc" and your're done. So simple :)