ARC with non-Foundation Objects - objective-c

I have made my own Objective-C base class to use in Objective-C projects (without Foundation/Cocoa classes or API). While I don't mind writing my own retains and releases, it's a tedious process so I'm wondering if I can use ARC with my custom classes.
Specifically:
Is it possible to use ARC with custom classes?
Do my reference-counting selectors have to be called retain and release (and autorelease)?
What additional requirements are there to make ARC work as expected for custom classes (other than including the -fobjc-arc argument when compiling)?

Is it possible to use ARC with custom classes?
Of course it is.
Do my reference-counting selectors have to be called retain and release (and autorelease)?
Yes, they do. Apple has hardcoded the method names of its favorite Objective-C library (Foundation) into the compiler. Damn bad programming pattern, isn't it?
What additional requirements are there to make ARC work as expected for custom classes (other than including the -fobjc-arc argument when compiling)?
As far as I know, nothing.

Related

Can Swift do everything that Objective-C can do?

I am new to IOS developing, and want to use the Swift language instead of Objective-C.
I know few concepts about Cocoa touch, and I want to know : Can Swift do everything that Objective-C can do ?
There are a lot of things that can be done in Objective-C but cannot be done in Swift, without implementing it in Objective-C and then using it from Swift. Some of them include:
Catching Objective-C exceptions
Using C++ APIs (through Objective-C++)
Using NSInvocation, performSelector: and other ways of making calls dynamically where the method to call is chosen at runtime
Handling unimplemented method calls using forwardInvocation:
Provide a function for use in C APIs that take a function pointer
The only concept I know that is in Objective-C but not in Swift, is Key-Value Observing (KVO). You can use KVO for a Swift class to observe the property of an Objective-C class, but you cannot observe any arbitrary property of a Swift class. See this answer for more details.
This is an interesting question but essentially the answer must be NO because you can use Objective-C resources in swift using bridging-headers. Xcode automatically translates Swift to Objective-C and vice versa. However, if you cannot write Objective-C code then you cannot include your own custom objective-c classes in your swift projects!
It all depends on how you like to code. Apple have said that Objective-C is still a 'first class' language meaning that they are going to run Swift and Objective-C side by side for the foreseeable future. Personally I prefer Objective-C because you can use C very easily (as anything that is legal in C is also legal in Objective-C) added to which Swift is a more procedural in style where Objective-C is quite clearly object orientated.
It is worth noting that the Cocoa and Cocoa Touch classes are all objective-c classes and so it may be useful to have a working knowledge of Objective-C. I think the best advice I've heard so far is, if you have the time, learn both!

What is the fragile base class in Objective-C?

I'm reading a book of object-c. When talking about inheritence, the book says:
Methods use the self parameter to find the instance variables they
use.
The Objective-C compiler knows the layout of the instance variables in
an object because it has seen the #interface declarations for each of
these classes.
With this important knowledge, the compiler can generate code to find
any instance variable.
Then it says this can cause fragile base class problem:
The compiler works its magic by using a “base plus offset” mechanism.
Given the base address of an object—that is, the memory location of the first byte of the first instance variable—the compiler can find all other instance variables by adding an offset to that address.
When you access some instance variable in a method, the compiler generates code to take the value that self holds and add the value of the offset (4, in this case) to point to the location where the variable’s value is stored.
This does lead to problems over time.
These offsets are now hard-coded into the program generated by the compiler.
Even if Apple’s engineers wanted to add another instance variable to NSObject, they couldn’t, because that would change all of the instance variable offsets.
This is called the fragile base class problem.
Apple has fixed this problem with the new 64-bit Objective-C runtime introduced with Leopard, which uses indirection for determining ivar locations.
I don't understand why adding instance variable in NSObject can cause problem.
If NSOject changes, can't we just recompile the program so the offsets change accordinglly?
Edit: And what if we dont recompile, will the existing code just fail?
Yes, a recompile would fix things, but until you recompile, your program would be broken.
Imagine that you compile your app targeting 10.4. The compiler looks at the headers of NSObject and figures out what the appropriate offset is for each ivar in your subclass. Then 10.5 comes out and they add new ivars to NSObject. Anyone running your app on 10.5 will have problems, because the Foundation framework (which includes NSObject) was compiled against the 10.5 SDK, while your app is still relying on the layout that was present in the 10.4 SDK.
The fragile base class problem meant that Apple could not change the size of any framework class without crashing every app that did not recompile for the new SDK. While in an ideal world, developers would always release updates promptly, that's not reality. So until the fragile base class problem was fixed, Apple's hands were tied.
If Apple adds an ivar to NSObject, all of its subclasses would need to be recompiled, meaning a number very close to the 100% of all the Objective-C code ever written.
Do you see the problem now?
It's not impossible to solve, you just need to have every developer to recompile their code bases, but in the meanwhile every single Objective-C program out there would be broken.
As a further reference, here's a very nice article by Greg Parker on this subject: http://www.sealiesoftware.com/blog/archive/2009/01/27/objc_explain_Non-fragile_ivars.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.

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

Use of __attribute__'s in ARC-managed Code

When ARC came to Objective-C, I did my best to read through the Objective-C Automatic Reference Counting (ARC) guide posted on the Clang project website to get a better hang of what it was about. What I found there (and no where else) was mention of using __attribute__ declarations to signify to ARC whether certain code autoreleases its return value, for instance (__attribute__((ns_returns_autoreleased))), or whether it 'consumes' a parameter (__attribute((ns_consumed)), and so on.
However, it seems that the guide gives very little word on the actual level of necessity these declarations hold. Excluding them seems to make no difference, neither when running the static analyzer nor when running the project itself. Do these even make a difference? Is there any advantage to labeling a method with __attribute__((objc_method_family(new)))? No article I've found on ARC makes mention of these specifiers at all; perhaps an ARC guru can give word on what these are used for.
(Personally, I include all relevant specifiers just in case, but find that they make code obfuscated and messy.)
These attributes are expressly for abnormal cases, such as:
A function or method parameter of retainable object pointer type may be marked as consumed, signifying that the callee expects to take ownership of a +1 retain count.
A function or method which returns a retainable object pointer type may be marked as returning a retained value, signifying that the caller expects to take ownership of a +1 retain count.
You don't normally do these things, so you don't normally use these attributes. With no attributes, the normal behavior—the NARC rule, or perhaps under ARC I should say CAN—is what the compiler implements and expects.
There are two reasons to use these attributes:
In order to violate the CAN rule; that is, to have a method not so named that returns a reference, or a method so named that doesn't. The attribute documents the violation in the method's prototype, and may even be necessary to implement it, if the implementation uses ARC.
Working with Core Foundation types, including Core Graphics types. These aren't ARCed, so you need to use the bridging attributes to aid conversion to and from “retainable object pointer” types.
That's not necessary in most of the cases, since LLVM & Clang knows ObjC naming conventions. So if you follow the standard naming conventions of Cocoa, LLVM automagically assumes the corresponding family/return memory policy to follow.
Namely, if you declare a method named initWith... it will automatically consider it as the "init" family of methods, no need to specify __attribute__((objc_method_family(init))), Clang automatically detect it; same for the new family, etc.
In fact, you only need to use the __attribute__ specifiers when Clang can't guess such cases, which in practice rarely occurs (in practice I never had to use it), or only if you don't respect naming conventions:
Quoting Clang Language Extensions Documentation:
Many methods in Objective-C have conventional meanings determined by their selectors. For the purposes of static analysis, it is sometimes useful to be able to mark a method as having a particular conventional meaning despite not having the right selector, or as not having the conventional meaning that its selector would suggest. For these use cases, we provide an attribute to specifically describe the method family that a method belongs to.
So as soon as you respect the naming conventions (which you should always do) you won't have anything do to.
You should definitely stick to naming conventions wherever possible.
It's clearer to read.
Attributes can introduce build errors if there is a conflict.
ARC semantics combined with attributes are relatively fragile.