Is it possible to see Objective-C ARC output? - objective-c

In xcode, it's possible given some Objective-C code, to see the code it would output in Assembly.
Is it possible to see given ARC enabled code, to see the Objective-C that would be outputted by ARC?

It is not possible, because ARC does not produce Objective-C code. ARC is a compiler feature that modifies the assembly produced in the same way that enabling optimizations might do. You can't tell the compiler to show you "optimized" C code; the optimizations are not applied at the level of C code. Likewise, you cannot ask to see the "ARC-ified" Objective-C, because the ARC memory management calls are not applied at the level of Objective-C code.
If you really want to see where the memory management calls are being made, you'll have to look at the assembly.

ARC doesn't as such output Objective-C, it a phase of the compiler which alters the assembler/machine code the compiler produces - and as you noted you can see that in Xcode. However if you use a decompiler on the binary you should see a "MRC equivalent", which is as good as you'll get. Try Hopper - demo available, I've not used it myself, don't know the producers, etc. However it produces psuedo-code, which looks like structured assembly, not Objective-C. HTH.

Related

Does LLVM LTO(Link-time Optimization) have any impact on Objective-C codes?

AFAIK, LTO can reduce dead codes and do some cross-file inlining. However,
Objective-C is based on runtime. Whether a method is indeed called is resolved until runtime, so it's not possible to reduce dead methods in Objective-C at link time, right? For cross-file inlining, it couldn't happen either as a method's implementation can be replaced during runtime.
So, how could LTO affect Objective-C codes?
I'm new to LLVM, so any advice is appreciated.

How to programmatically detect automatic reference counting?

This might be a silly question, but I just wanted to know. I want my code to detect if ARC is enabled, programmatically. How do I do that? Is there is any flag that I could check? Actually the problem is that, I have written an open-source library. I have used release and retain in it. if some one else uses my library files using ARC enabled, I dont want them to get any errors. how do I achieve this? or is there any possible ways I can provide any tools to compile my library before using it?
#if !__has_feature(objc_arc)
//Do manual memory management...
#else
//Usually do nothing...
#endif
This is of course a compile-time check, you cannot check for ARC at runtime.
An alternative would be to set the -fno-objc-arc compiler flag for your files that use manual memory management in a project that otherwise uses ARC.
Whether you want to bother with this at all or just use ARC everywhere depends on how backward-compatible you want/need to be. Code that supports both ARC and MRC can get quite hard to read and maintain.
You don't detect it programmatically, it operates based on translations. That is, it is not like Garbage Collection -- which is process-wide, required all linked libraries to support (and implement it correctly in that mode). You can have some files compiled with ARC, and some without.
However, you can detect it at compilation.
As far as the distribution of your library: I would not bother with a translation based system, where ref count ops are conditionally enabled. I would (personally) just support one model (MRC in your case, until you choose to migrate it to ARC), then expect people to link to the library, or if they compile it in a target they configure, to disable ARC. Conditionally enabling/disabling code based on the presence of a feature is asking for tough bugs, particularly when it's likely to affect 9% of your library's lines of code.
NO, you can't, Xcode would not compile in ARC projects if your source uses retain-release

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 :)

GCC_ENABLE_CPP_EXCEPTIONS and Objective-C

I have a pure Objective-C project (no C++ anywhere). Can I turn off GCC_ENABLE_CPP_EXCEPTIONS or do Objective-C exceptions rely on this?
If you're not using any C++ code, you can turn it off (it only applies to C++ code). Or you can leave it on -- it won't really matter either way.

Under automatic reference counting, why are retain, release, and dealloc not allowed?

When trying to use -retain, -release, and -dealloc while building my application using automatic reference counting in Xcode 4.2, I get an error like the following:
Automatic Reference Counting forbids
explicit message send of 'dealloc'
Why am I seeing this error? Are -retain, -release, and -dealloc no longer allowed under automatic reference counting?
Basically:
When using ARC, it's all or nothing. Either the compiler is managing all of the retains/releases/deallocs for you, or it is doing nothing. You cannot intersperse your own calls to them, because the compiler wants to do it all itself. It can make absurd optimizations by doing this (for example, a method that returned an autoreleased object under Manual Memory Management may now produce an object that never ends up in an autorelease pool). If you were to start sprinkling in your own calls to retain and release, then the compiler would have to work with these and wouldn't be able to perform a lot of the optimizations that it wants (and that you should want).
And as an added bonus, invoking -retainCount is now a compiler error! OH HAPPY DAY!
in response to AliSoftware: we CNA mix ARTC and not-ARC frameworks, and also arc and not-ARC source.
(I did it..)
The basic ideas are:
1) compiler will insert/remove calls as a very-very-good cocoa programmer can do
2) cocoa is ANYWAY C code, so we have separate compilations, so the linker CAN link binaries produced by multiple sources. Think it as we can mix asm and cocoa, or C and pascal...
in main opinion the Appleadvantege over c# / java is here: we are alway allows to mix, and, using a COMPILER technique 8non a runtime..) we can rush performance beyond.
Under automatic reference counting, retain, release, and dealloc are not allowed.
If you have an existing code, you can keep using it as is with the -fno-objc-arc you can selectively disable ARC on any file.
If you want to disable ARC on MULTIPLE files:
Select desired files at Target/Build Phases/Compile Sources in Xcode
PRESS ENTER. (double click selects only one file)
Type -fno-objc-arc
Press Enter or Done
As I have pointed out in my answer on Xcode ARC, you can compile specific source files as non-ARC. Dave DeLong's answer is a bit off. It doesn't include the fact that you can instruct the compiler to compile source as non-ARC in an ARC-enabled project (as explained here).