I noticed that there are variables and functions used by many libraries that start with CF and ends with Ref, like: CFStringRef , CFURLRef , CFHTTPMessageCreateRequest , etc ...
1) what does CF stand for ? I don't know why apple does not say a word about such abbreviations.
2) what's the benefit(s) of using (for ex.) CFStringRef instead of using NSString ?
3) if it's better to use these CF variables, should I then replace all regular variable like NSString with CFStringRef ?
CF stands for Core Foundation. If you're interested in learning more about that, you can start by reading the Core Foundation Design Concepts Guide. There are also the String Programming Guide for Core Foundation and Collections Programming Topics for Core Foundation, which will tell you more about CFStringRef and the various collection types (arrays, dictionaries, and so forth).
Basically, Core Foundation is a relatively low-level framework that does some of the same things that Foundation does, but is written in C, and not Objective-C. Some Core Foundation "classes" (they're not really classes) are also "toll-free bridged" with their Objective-C counterparts, for example, it is possible to cast a CFStringRef to an NSString * (though it is a little more complicated with ARC).
If you don't need specific APIs that are only available in Core Foundation, there's absolutely no need to use it instead of Foundation. Core Foundation code tends to be less readable than Objective-C and also makes memory management a bit more complicated.
However, it can be quite useful to familiarize oneself with the basic concepts of Core Foundation, because there are still quite a few other frameworks that are built similarly. Core Text and Core Graphics are examples – while they don't formally belong to Core Foundation, they use the same naming and memory management conventions. There are also some APIs that are only available in Core Foundation and don't have Foundation counterparts – CFBagRef or CFBitVector (both collection types) would be examples.
From the Apple documentation:
Core Foundation is a library with a set of programming interfaces conceptually derived from the Objective-C-based Foundation framework but implemented in the C language. To do this, Core Foundation implements a limited object model in C. Core Foundation defines opaque types that encapsulate data and functions, hereafter referred to as “objects.”
This is essentially sums up the difference. Core Foundation (CF) provides pure C implementations of many of the Objective-C implementations that come with the language in the form of the Foundation framework. It is correct that NS stands for 'NeXTSTEP', the name of the operating system that formed the absis for much of Mac OS X, but it also indicates that a type is an Objective C class. CF types are pure C implementations and come with C functions to manipulate them.
There are occasionally times that using the CF structures brings an advantage over the NS equivalent. For example, CFDictionary places fewer restrictions on values and keys than does NSDictionary. But unless any such problem comes up there isn't a reason for you to change your references to their CF equivalents. ARC will also not work as easily with CF types.
It is also possible to map between CF and Foundation using toll-free bridging.
Objective-C is built on the c language, the CF (Core Foundation) types are C structs, and are usually wrapped in an Objective-C object (CFStringRef is wrapped by NSString, CGImageRef is wrapped by UIImage etc)
Unless you have a good reason, use the Objective-C level code. The memory management is much simpler (automatic for ARC), and in general your code will be much cleaner
Edit: as #omz pointed out, wrapped is incorrect for NSString, it is bridged, some of the other answers explain this concept
Related
Question
- What is the difference between Swift Foundation and standard library?
I know they are not in the same repository. Swift standard library and Swift Foundation.
My understanding is that Swift standard library is low level library that are support for core data types, array, etc... written in swift. And Swift Foundation is for higher level which are already included common utilities codes written in swift language. But my confusion is that why are the objective-c classes like NSArray are included in Foundation library? Can you explain me with more details?
To understand what's going on here, first distinguish three things:
Swift library is the Swift native types, like String and Array.
Foundation is the Cocoa Objective-C basic set of types, like NSString and NSArray and NSDate and NSData.
Swift also contains an overlay library that shadows (without obscuring) types in the Foundation. For example, Date shadows NSDate, and Data shadows NSData. This makes the Cocoa Foundation a lot easier to use in Swift.
Note that there are two very different relations in which a Swift type can stand with respect to a Cocoa Objective-C type.
String and Array are completely independent native Swift types. They are bridged to NSString and NSArray respectively, but they exist without Foundation.
Data and Date are merely facades for NSData and NSDate respectively. If you import Swift but not Foundation, Data and Date are not even present.
Okay, so far so good. But this situation presents a quandary, because one would like to use Data and Date without the need for Foundation, in places like Linux that do not have it in the first place. Therefore, the project you have pointed to, https://github.com/apple/swift-corelibs-foundation, provides a backing for Data and Date (and so on) independent of Foundation.
But if you are developing for iOS or MacOS you would never use it, because the real Foundation is present.
Swift Standard Library
NeXTSTEP -> Cocoa -> Swift Standard Library
[Cocoa]
Swift Standard Library:
describes fundamental data types, protocols, functions... their definitions and algorithms to work with
implementation - swift/stdlib/public/
Standard library core - swift/stdlib/public/core/ - data structures and algorithms
Runtime(Swift Run Time Library) - swift/stdlib/public/runtime/ - low level stuff which written on more low level language(C++, Objective-C) which is a layer between compiler and Standard library core. It responsible for dynamism(runtime features) - memory management, reflection...
SDK Overlays - which helps to support compatibility with Swift with Objective-C
Swift Foundation - swift/stdlib/public/Darwin/Foundation/ -> swift-corelibs-foundation is a part of SDK Overlays which allows you to work with Objective-C Foundation framework from Swift codebase.
[Binary representation]
After not programming for a long, long time (20+ years) I'm trying to get back into it. My first real attempt is a Scrabble/Words With Friends solver/cheater (pick your definition). I've built a pretty good engine, but it's solves the problems through brute force instead of efficiency or elegance. After much research, it's pretty clear that the best answer to this problem is a DAWG or CDWAG. I've found a few C implementations our there and have been able to leverage them (search times have gone from 1.5s to .005s for the same data sets).
However, I'm trying to figure out how to do this in pure Objective-C. At that, I'm also trying to make it ARC compliant. And efficient enough for an iPhone. I've looked quite a bit and found several data structure libraries (i.e. CHDataStructures ) out there, but they are mostly C/Objective-C hybrids or they are not ARC compliant. They rely very heavily on structs and embed objects inside of the structs. ARC doesn't really care for that.
So - my question is (sorry and I understand if this was tl;dr and if it seems totally a newb question - just can't get my head around this object stuff yet) how do you program classical data structures (trees, etc) from scratch in Objective-C? I don't want to rely on a NS[Mutable]{Array,Set,etc}. Does anyone have a simple/basic implementation of a tree or anything like that that I can crib from while I go create my DAWG?
Why shoot yourself in the foot before you even started walking?
You say you're
trying to figure out how do this in pure Objective-C
yet you
don't want to rely on a NS[Mutable]{Array,Set,etc}
Also, do you want to use ARC, or do you not want to use ARC? If you stick with Objective-C then go with ARC, if you don't want to use the Foundation collections, then you're probably better off without ARC.
My suggestion: do use NS[Mutable]{Array,Set,etc} and get your basic algorithm working with ARC. That should be your first and only goal, everything else is premature optimization. Especially if your goal is to "get back into programming" rather than writing the fastest possible Scrabble analyzer & solver. If you later find out you need to optimize, you have some working code that you can analyze for bottlenecks, and if need be, you can then still replace the Foundation collections.
As for the other libraries not being ARC compatible: you can pretty easily make them compatible if you follow some rules set by ARC. Whether that's worthwhile depends a lot on the size of the 3rd party codebase.
In particular, casting from void* to id and vice versa requires a bridged cast, so you would write:
void* pointer = (__bridge void*)myObjCObject;
Similarly, if you flag all pointers in C structs as __unsafe_unretained you should be able to use the C code as is. Even better yet: if the C code can be built as a static library, you can build it with ARC turned off and only need to fix some header files.
I want to write some straight C code that uses some Foundation types. For now, I want to use NSInteger, NSUInteger, and NSRange; I can imagine wanting others later. Is there a header somewhere I can import that will get me these types without causing trouble in a straight C file?
Not Foundation, but you can use Core Foundation (<CoreFoundation/CoreFoundation.h> or more specifically CFBase.h), and the equivalent types CFIndex, CFRange, etc.
I've written a few small programs in Objective-C (for the iPhone) but ultimately I want to write my programs mainly in C++. (I just find it a lot easier.)
If this is true, how would I:
Manage memory in C++? (Does C++ have a release-like command I need to use?)
Intermix C++ and Objective-C coding? (Or even, should I?)
Take a C++ object, like a string, and convert it into an NSString?
Thank you!
Derek
Yes. C++ has a delete keyword, but it only applies to objects you've created with new (which, for idiomatic C++ code, is not every object). C++ also doesn't have built-in reference counting, just pure ownership.
If you make a source file with a .mm extension, it compiles as Objective-C++, which lets you intermix Objective-C and C++ code.
For a string, you can call std::string::c_str() to get a string that you can pass into +[NSString stringWithUTF8String:].
My two cents: if you feel that C++ is a lot easier than Objective-C and you don't know anything about memory management in C++, you should try to spend a fair amount of time learning pure C++; it's extremely easy to shoot yourself in the foot in C++ if you don't know what you're doing.
Manage memory in C++? (Does C++ have a release-like command I need to use?)
c++ uses new and delete. specifically, c++ programs prefer to use scope-bound-resource-management (SBRM). managing dynamic allocations is dead easy when you use these containers. reference counting, however, is not currently built into the language -- you can use boost www.boost.org for more advanced pointer containers, including those which offer reference counting.
Intermix C++ and Objective-C coding? (Or even, should I?)
you can easy accomplish by using the extension .mm or .M, or by using a compiler flag. note that you should not just enable everything as objc++ -- this will hurt your build times. also note that there are a few restrictions, including the inability to subclass c++ types as objc types and vice-versa. another important flag which any sane c++ dev would enable is the one which generates c++ constructor/destructor calls when you use c++ types as variables in your objc classes. otherwise, you'll just crash, be forced to use pimpl, or have to manually construct/destruct all your c++ instances (as ivars in objc types). this means these types you use will all need default constructors. you can intermix the languages, it's fine to do this if it is your preference. there are a few more notes on mixing them in apple's docs, but those are the important ones... oh, and be careful to quarantine your exceptions (which you must also do with objc).
Take a C++ object, like a string, and convert it into an NSString?
see John Calsbeek's response
good luck
What is the difference between NSMutableArray and CFMutableArray?
In which case(s) should we use one or the other?
CFMutableArray and NSMutableArray are the C- and Objective-C-equivalents of the same type. They are considered a "toll free bridged" type pair, which means you can cast a CFMutableArrayRef to a NSMutableArray* (and vice versa) and everything will just work. The cases in which you would use one over the other is ease-of-use (are you using C or Objective-C?) or compatibility with an API you would like to use. See more information here.
At runtime, they are identical. They are the same, they are toll-free bridged types - you can safely (and efficiently) cast one to the other.
They are different types, available in different/overlapping languages.
CFMutableArrayRef is the opaque C object interface
NSMutableArray * is the Objective-C interface
They may be freely interchanged, and the difference is the declaration that says one is a pointer to an opaque type, vs a objc object.
Also, you can (sorta - it requires a little more implementation than usual) subclass NSMutableArray type using objc.
OSX's APIs are layered, there are basic low-level APIs that are self-cotnained and then there are richer APIs built on top of them, in turn using the lower level APIs themselves.
CFMutableArray is part of the CoreFoundation framework and used by the lower-level APIs. NSMutableArray (I guess NS stands for NextStep) is part of the Foundation framework and used in higher level APIs like the AppKit or Cocoa.
Which you should use depends on where you are working. If you're working in a rich user interface using Cocoa, NSMutableArray is the right choice. If you're working on a daemon, driver or anything else just using CoreFoundation, use CFMutableArray.
Luckily, as pointed out above, many of these CF/NS types are toll-free bridged and so you can use CoreFoundation APIs from e.g. Cocoa without having to constantly convert types.