CF objects vs NS objects - objective-c

I'm trying to understand why there exists both CF and NS objects, which seem to do the same thing and are interchangeable through toll-free bridging. If, say, CFArray and NSArray do the same thing, and I can cast between them freely, what's the point in both of them existing? Are there rules of thumb about when to use one over the other? Are the CF objects just legacy objects from old frameworks? Any insight into this would be greatly appreciated.

To answer your questions in order:
What's the point of them both existing? There are a few reasons.
If you want to provide a C API, like the Carbon API, and you need things like arrays and dictionaries of referenced-counted objects, you want a library like Core Foundation (which provides CFArray), and of course it needs to have a C API.
If you want to write libraries for third-parties to use on Windows (for example), you need to provide a C API.
If you want to write a low-level library, say for interfacing with your operating system's kernel, and you don't want the overhead of Objective-C messaging, you need a C API.
So those are good reasons for having Core Foundation, a pure C library.
But if you want to provide a higher-level, more pleasant API in Objective-C, you want Objective-C objects that represent arrays, dictionaries, reference-counted objects, and so on. So you need Foundation, which is an Objective-C library.
When should you use one or the other? Generally, you should use the Objective-C classes (e.g. NSArray) whenever you can, because the Objective-C interface is more pleasant to use: myArray.count (or [myArray count]) is easier to read and write than CFArrayGetCount(myArray). You should use the Core Foundation API only when you really need to: when you're on a platform that doesn't have Objective-C, or when you need features that the Core Foundation API provides but the Objective-C objects lack. For example, you can specify callbacks when creating a CFArray or a CFDictionary that let you store non-reference-counted objects. The NSArray and NSDictionary classes don't let you do that - they always assume you are storing reference-counted objects.
Are the CF objects just legacy objects? Not at all. In fact, Nextstep existed for years with just the Objective-C Foundation library and no (public) Core Foundation library. When Apple needed to support both the Carbon API and the Cocoa API on top of the same lower-level operating system facilities, they created (or made public) Core Foundation to support both.
Incidentally, some of Core Foundation is open source. You can find the open source part of it for Mac OS X 10.10.5 here: https://opensource.apple.com/source/CF/CF-1153.18/. I have found the source code of CFRunLoop and CFStream to be very informative.

Core Foundation is a C API to a variety of common data structures. Most of these data structures have equivalents in Cocoa, but not all of them. Most of the ones that are equivalent are toll free bridged, allowing them to be used interchangeably, but not all of them either.
Toll free bridging is a very clever implementation trick. If you want the underlying details, see the ridiculous_fish post that #Matt Wilding points out. It's the most authoritative on the subject (and a major influence on iOS:PTL chapter 19 which also explains how it all works). But it doesn't really matter for most purposes. As Matt notes, you can generally pretend that an NSArray is the same as a CFArrayRef. This isn't really true in many cases, but it's sometimes true, and close enough most of the time. It's the same as saying that #"stuff" is the same as an NSString containing stuff. It's mostly true, but not exactly.
When OS 9 moved to OS X, it was very convenient to provide C access to Objective-C-like data structures. Many low-level frameworks today expose C APIs for performance reasons. You shouldn't think of CF as "legacy" or "internal." You should think of it as low-level and you should only use it when you need the power it provides, or are dealing with a low-level framework that requires it.
CF objects are often more flexible than their NS counterparts. For example, CFDictionaryRef can contain non-object keys and values, while NSDictionary can't. (Of course they're toll-free bridged, so you can create a non-retaining CFDictionaryRef and then treat it as an NSDictionary. Tricky that....)
As Apple releases new frameworks, you'll notice that they often expose C APIs first, and then later add Objective-C APIs. This is a reason that it's a good idea to learn Core Foundation, even if you don't use it every day. But when possible, you generally should be using ObjC.

There's some history to this question. Core Foundation is the brains of the operation. It's written mostly in C. It was created with Apple's acquisition of NEXT and their APIs and owes a lot to them. The NS* classes are often just Objective C abstract interfaces built on top of the CF* types. So, when you ask why both CFArray and NSArray exist, the answer is that they actually don't. NSArrays are CFArrays, NSStrings are CFStrings, etc. That's why toll-free-bridging is possible.
For more interesting and detailed reading, I would refer you to this blog post.

CF stands for CoreFoundation. Exposed objects with CF in their names are just regular Core Foundation objects, written in C. All objects are toll free bridged with their Cocoa Touch Foundation friends over in Objective-C land. They are usually opaque pointers.
NS stands for NextStep, which was the old OS that Mac OS X was built upon. NS-prefixed objects are usually written entirely in Objective-C or C or even some C++.
It really depends on what you need each object to do. It's certainly easier for me to work in pure Objective-C with NSString, then it is for me to work in a mix of C and Objective-C with CFString, but there are some things that CF objects can do that NS objects simply can't (mostly very low level stuff). CF objects also dabble a lot more in Ref's, mutations, and inspections than their NS counterparts.
(For future reference, there exist a few more prefixes: CG for CoreGraphics, UI for UIKit, QL for QuickLook, AV for AVFoundation, MP for MediaPlayer, MF for MessageFoundation, GL for GLKit, and MK for MapKit)(If I've missed any, I'll gladly edit).

Related

Project without garbage collector osx

in my school we recieved task to do project in any programming language, but with custom data structure and programming language can not have garbage collector. It was recommended to use C ++. But I have better skills in objective-c. So I disable ARC in my Xcode project and now I should create custom data structure like ArrayList in Java. I cant use NSMutableArray or NSArray. It is possible working with memory like in C++ and create custom data structure?
Thank you for response
You have two basic choices:
Use struct's for your data structures and malloc/free (and friends) for your dynamic memory allocation - just as you might in C(++); or
You can use NSObject derived classes and alloc/init/new/retain/release (and friends) for your dynamic memory management. To do this you must disable ARC.
Given this is a school task you might wish to check the second is acceptable - you are still using the Objective-C reference-counting machinery, even though you are calling the operations manually. Your professor may not deem that acceptable.
The first choice is more basic, you will be completely responsible for all decisions on when memory is no longer required. Indeed you may choose to implement your own reference counting or even mark-sweep.
HTH

What does it mean to share an implementation?

As the title notes I'm looking to understand what does it mean to share an implementation. To be more specific, I want to know HOW it works. I get what the words mean but I'm not clear on the process of how it works.
Ex. "The fast-enumeration implementation is shared between the Objective-C runtime and the Foundation framework."
This is from Apple's Cocoa Fundamentals doc. I was reading and came across this line and am trying to understand the process.
Thanks
This basically covers a somewhat contradictional programming pattern (which, in my opinion, is wrong): the Objective-C language, the libobjc runtime library and the Foundation framework aren't strictly separated. For example, some fundamental message names, such as retain, release, etc. are hard-coded into the Objective-C runtime library (e. g., in order ARC to recognize these as special memory management-related messages), and this is the case with the fast enumeration as well.
The countByEnumeratingWithState:objects:count: selector is recognized by the compiler, and it is emitted when the for (object in collection) syntax is encountered. Then the collection object, of which the class implements this hard-wired message of the protocol NSFastEnumeration, updates count, objects, its return value, etc. according to how the runtime library and the ABI expects it.
For historical reasons, there's such a tight coupling between these three things (the language/the compiler, the runtime library and the Foundation framework) that this hard-coding approach is usable and realistic, but it's also a terrible violation of separation of the language and the library. I even dare to say that this is a quite dirty hack.

Cocoa Programming in C?

I would like to start programming on Mac. Please:
I don't really like Objective-C and I somewhat know C, I read that Objective-C is a "dialect" of C - is it possible to program in C and use all the libraries and frameworks provided by Mac OS (this is Cocoa, right?)?
is it possible to draw GUI in XCode's GUI Builder and then fill the logic in plain C?
if I want to use, say, Scintilla - how do I "load" its text editing component into a window in GUI builder? And how do I access its text buffers? And events?
Just learn Objective-C. It isn't that hard; much, much, simpler than, say, C++. The object model is extremely similar to Java or SmallTalk.
The entire Cocoa stack of APIs are all in Objective-C, the documentation is all in Objective-C, many of the design patterns (KVO, KVC, delegation) are inherently Objective-C isms and all of the examples are Objective-C.
You are going to have to have a working knowledge of Objective-C to effectively program the system anyway. Any attempts to avoid Objective-C is just going to make your job harder, yield less maintainable code, and vastly reduce the # of folks in the community who can help.
Sure, by interacting with the runtime directly. It means you'll be doing a lot of objc_msgSend() et al. It's going to be horribly painful, you might as well just learn the Objective-C syntax and be done with it. (I explicitly note the syntax, because you will still need to learn the way objc does things in order to even use the C APIs).
The bit I can be least helpful on first: without having heard of it, according to its website Scintilla is for win32 and GTK+. As I believe that there's still no Cocoa native version of GTK+, there is no way to use a Scintilla component in a Cocoa program. OS X is not based on X11 (or Win32, for that matter).
Objective-C adds Smalltalk-style objects and dynamic dispatch to C. However, it is a strict superset, so C code is directly callable. The various GUI components rely on the dynamic, reflective nature of Objective-C so cannot directly call C code. However, the whole toolkit is built around the model-view-controller paradigm. It is quite feasible to design your view in Interface Builder, write a thin shim of a controller in Objective-C that does little more than call appropriate C functions and write your model entirely in C. C code can call Objective-C code, so you can wrap as many of the system objects as you want.
So this i pretty much a 'yes' to your second bullet point. Also relevant is that although Objective-C springs from C, Apple have made C++ fully callable (search for Objective-C++), so that's also an option.
Well worth looking into is Core Foundation. OS X originally supported two top-level programming environments — Cocoa and Carbon. Cocoa is Objective-C, Carbon is C with a bunch of legacy support libraries (and is now deprecated, with no 64 bit runtime to be supplied). To support both of these, much of the core system functionality is exposed through C interfaces at the lowest level, including all collections, strings and other relatively primitive objects. A bunch of other performance critical things like Core Text, Core Graphics, etc are also normally done via a straight C interface, even if you're otherwise completely enthusiastic about Objective-C.
There is a C-based API for UI programming on Mac OS X called Carbon. If you really cannot stand the sight of Objective-C I would start there. Many Cocoa classes and APIs have corresponding Carbon datatypes, etc. and vice versa but not all of them. Fair warning, Carbon is considered a "legacy" API, and it will likely continue to be marginalized as time goes on. Many Carbon APIs are not available for 64bit applications for example
Cocoa specifically is an Objective-C based API, using it from C would be awkward and difficult if possible at all. It would require some knowledge of Objective-C runtime APIs and possibly internals or otherwise writing a bunch of wrappers.

Objective-c and c++ on linux

I have some maybe stupid question. What is the difference between C++ and objectice-c. Is there IDE for objective-c for linux ?
I'm going to expand a bit on DaVinci's point 1.
First the similarities:
Objective-C and C++ were both originally based on C. Both languages support an object oriented model. That's where the similarities end.
Objective-C is a strict superset of C, C++ is not. Any C program is also an Objective-C program. This is not necessarily the case with C++.
The syntax of Objective-C's OO extensions is closer to the syntax of Smalltalk than that of C whereas the reverse is the case with C++.
The philosophies behind the OO models is completely different too. Objective-C's model is dynamic in the spirit of Smalltalk. C++'s model is more static. With Objective-C, you send messages to objects and the object decides at run time how it is going to respond to the message. With C++ the methods that an object responds to - even the virtual ones - are defined at compile time. This makes Objective-C's object model immensely more powerful than C++'s object model. For instance, you can add whole sets of new methods to existing classes without using inheritance. You can even replace method implementations on the fly.
This all comes at a cost of course. Sending messages to Objective-C objects is quite a bit slower than calling C++ virtual functions. However, I think the benefits are worth the cost and you can always drop back to C for performance critical sections of code.
NB there is also a language called Objective-C++ which is the Objective-C OO extensions built on top of C++ instead of C.
they are simply two quite different languages.
I think gnustep is the only objective-C environment/library, it also has a IDE: project center, however Objective-Cs home is primarily on Apple products.

What's the difference between Objective-C and Cocoa?

I'm just learning Objective-C/Cocoa programming for the Mac. All of the tutorials, books, blogs, podcasts, etc. I've been using really cover the two together. Is there an easy way to tell which pieces are vanilla Objective-C and which come from Cocoa?
Objective-C is the language... it defines all the things like the keywords for defining objects, the syntax for messaging object, things like that.
Cocoa is a development framework (it's actually an umbrella framework which combines three other frameworks, Foundation, AppKit and CoreData).
These frameworks (Cocoa) define all the objects that are nice to use and interact with the operating system, as well as a number of functions. For example, Cocoa defines things like NSString and NSObject. Cocoa can currently be used with other language bindings, such as python or ruby, and used to be used with Java as well. So, if you were using Cocoa with Java, you would still get an NSString object, but you would call and use it from within a Java application.
Without linking to one of the Cocoa frameworks, Objective-C comes with only a very basic Object class as a pre-defined root class.
Objective-C is the language itself.
Cocoa, formerly NextStep, is the API and runtime that sits on top of Obj-C. Anything starting with NS (for NextStep) is part of Cocoa, not part of the language.
Sure, it is quite easy - Objective-C is the language, Cocoa is the API/library you are using to build you Mac App.
Look in /usr/include/objc/ — in there is pure Objective-C. Everything else is Cocoa. You might notice you almost never directly use anything in there.
However, in practice it makes little difference. Cocoa is the de facto Objective-C standard library. The only platform where Objective-C is used without Cocoa is Portable Object Compiler, and I'm guessing maybe three people still use that.