---
title: WWDC2000 Session 124
framework: wwdc
role: article
path: wwdc/wwdc2000-124
---

# WWDC2000 Session 124

## Transcript

Kind: captions Language: en we're going to start by talking about CF role in Mac OS 10 as a whole then we're going to look at some of the concert there and finally in this talk will be introducing the basic CF type so when I talk about core foundation this is the big take-home point core foundation is the lingua franca in Mac OS 10 well what does that mean a lingua franca is a medium of communication between people of different different languages so what are the different languages on Mac OS 10 carbon and coco coir foundation is a substrate layer that lives beneath both carbon and Coco so it provides the common language by which those two environments speak to one another as such it bridges the basic types between both stacks and provides those common services that both stacks need to share things like the pasteboard the event model so just as an example here you see the carbon types on the right and the cocoa types on the left corefoundation acts to convert to and fun to and from the types on either side hopefully you've seen this diagram by now this is the basic architecture on Mac OS 10 I want to point out the core services layer that lives below the application services the graphical services like quartz and OpenGL and QuickTime but above Darwin the operating system that layer is where we live we provide the common services needed by everything above us that does not depend on graphics so if you look inside the core services layer you'll see a number of the non graphical managers you're familiar with things like the file managers memory manager resource manager and in with all of those is core foundation in fact core foundation were you to look inside the core services code lies below almost all of those there we go so what is CF it's a non graphical substrate library available to both carbon and cocoa in fact it's even below classic it is written in you're see because that is the common language beneath all of those layers and it's designed around some basic object-oriented paradigm so CF provides two basic things to the system the first one is some basic types by which all of the different substrates can speak so that's things like strings arrays and dictionaries and then we combine them together in an abstraction that we call property list the other thing it provides is the non graphical services that every application needs so that's local ations the localization support user preferences as I said also the pasteboard and the run loop in this talk we're going to focus on the basic data types there's a follow-on to this talk immediately after lunch in the same room where we'll be talking about the second half of that stack the not the app services so where is CF available on Mac OS 10 this core foundation is available as its own library on eight and nine it ships as part of carbon live now there's a there are some pieces of core foundations that are only available on 10 those centres around the mock specific pieces which obviously do not apply on eight and nine finally a subset of core foundation is available inside of Darwin so if you're interested you can check out the Darwin source code and see what we're doing right so I know that it's a developer when I go and approach a stack one of the first things I I don't want to hear is by the way this is this other large API I have to learn so if you don't want to learn CF relax you don't really have to you're missing out but you don't have to carbon and cocoa are both complete ap is on to themselves you can write entirely to those api's if you wish and core foundation will silently help out underneath the stats providing smooth communication however this is what you're going to miss if you yourself need to need to write code that bridges between carbon and cocoa applications for instance if you're writing a low-level library that several several different applications are going to use you should be using CF to convert the types to and from internationalization support is wired into core foundation it's one of the easiest places to get it from there's a rich simple set of data types around those internationalized strings inside of core foundation that's what we're going to focus on here today and there is some new functionality which you can only get by talking to the core foundation stack so what is that new functionality property lists is a big one and that's the one we'll talk about today there's also an an XML parser inside of course foundation it's not the only XML parser on the system but it's the only one in C and it's nice and low level for your use user preferences there's a unified user preferences model inside of course foundation it will save you from having to invent your own preferences file format and doing your own work of reading and writing to file finally and perhaps most importantly the bundle and plug-in model that surrounds the entire app packaging scheme on Mac OS 10 is centered in core foundation so if you want to pull apart the pieces of that app packaging format you should be talking to core foundation ok so now I'm going to move on to talk about the basic concepts and paradigms inside of core foundation I'm going to spend a moment on the general philosophy of the library then I'm going to talk about how we managed to get some object orientation inside of what is a purely see light on C library and finally I'm going to look at the memory management scheme that we use the general philosophy of core foundation is to be lean and mean we are just barely above the operating system layer performance and efficiency is perhaps our primary goal for that reason we have exported a minimal API and tried to make it as powerful and extensible as possible so you will not find a lot of convenience functions to do simple operations you will find some complex powerful functional API where you may have to you may have to do some configuration of the arguments going in finally there is no safety net in course foundation we follow the same philosophy as the C language if you tell us to do something we're going to do it no questions asked so if you hand us a bad pointer we're going to try and access it to try and ease the road a little bit we do provide a debug library and that debug library is available so that as you code you can run against it and it will catch a number of common errors and that way you can help you can start to debug your program so object orientation inside of course foundation focuses on CF types and we try to make this as available as possible in the maiming inside of course foundation so each type is going is opaque and represents a pseudo class and each such type is going to be named CF and then the class name ref the related functions which are acting as methods on the class will always be prefixed with the name of the class CS class name and then in action describing what the function does related constants also are prefixed with the class name k CS class and then a descriptor so for example if we look at CF strings the type of CF string ref an example of a function would be CF string append and an example of the constant would be KCF string encoding ascii furthermore inside the functions the first argument is always the type instance what you would consider the receiver if you were writing in a true object-oriented language then there's one important exception to that and that's creators and we'll get to those in a minute we use common verbs to have common meanings throughout the throughout the API so that CF array get array add is going to work the same way as CF dictionary add finally when we are passing information back to you we will always put those out parameters the ones that are going to be passed by reference at the very end there are a small number of polymorphic functions inside of CF this is the entire list this these functions can be used with any CF type regardless of class so I equality and hashing so you have to equal um c of hash that's what allows us to add at add objects into collections and retrieve them out of it there's a little bit of interest introspection CF get type ID will return the type ID of the class CF copy description will provide a string description of the object this is for debugging purposes only these are not intended to show to the user in fact it will frequently have the hex address of the of the object embedded in them and finally memory memory management we use a reference counting memory management scheme so CF retain gains a reference CF release releases it CF def retain count is intended for debugging purposes only so you can track how the reference counting goes through an object's lifetime and then CF get allocator allows you to discover how the object was allocated so as I just said CF types of reference counted retained to get to take a reference release to release it anytime you have a reference counting screen you have this common problem of who gets who has the reference when an object is returned by a function here are the rules very very simple if the function you called includes the word get you did not get a reference the object you called retains the reference so if you intend to keep that object you'd better retain it yourself functions that include the words copy or create on the other hand give you a reference and when you are done with that object you must release it or else you will have a leak there is something important to keep in mind here we are simply using copy and create as as a way of telling you the developer whether or not you've got a reference there may be some optimizations going on the back particularly in the case of immutable objects so even though you've received a reference copy may not actually do any copy memory copying and likewise create may not do any allocation CF is simply being more efficient and it shouldn't matter to you allocators an alligator there is a type for at CF allocator ref an alligator encapsulate an allocation scheme it you call an alligator to allocate memory to release it to reallocate it and so on and every create function so every function that could create a CF object takes an alligator as first argument and uses that alligator to create the memory necessary normally you're going to want to pass KCF allocator to default which asks CF to use whatever the current default allocator is there's one we have one that we installed by default if you want to you can install your own to do custom memory management that's all I'm going to say on the basic structure of CF or the basic concepts and now I'm going to move on to talk about some of the basic types inside of core foundations we're going to start with CF string because that's probably the most basic of the types the one that you're most likely to be using then we're going to talk briefly about CF array and CF dictionary which are two of our collection types once we're done with that we'll look at how collections and mutability work together inside this library and finally we're going to see how all of that comes together to form property list conceptually a CF string is simply an array of Unicode characters the goal in creating a CF type whereas I show here we're trying to get strength to a new level of abstraction we're trying to solve the 8-bit ASCII problem if we can do that then internationalization becomes easy because the basic type throughout the entire system will support Unicode characters because we're at such a low level we've worked hard to assure performance so even though conceptually you're looking at an array of Unicode characters it may not internally be stored that way in particular you're not always going to be storing two bytes per character and as we move forward CF strings are becoming the way to communicate strings in all of the public api's CF string maintains a very rich functionality set there are a number of different creation functions depending on where you may have gotten the your string data from whether it's coming from a carbon stack or or cocoa or you just read it out of a file there's a lot of support for encoding conversions from CF strings to whatever encoding you need to use we will do comparisons find searches there are some more complex operations like exploding a string into its component pieces or combining the component pieces back again and there's even some printf style formatting and parsing available so let's look at some of the API for creation and access I give an example of a couple of the basic creation methods here CF create with characters allows you to take an array of Unicode characters and create a string out of it pretty straightforward if on the other hand you're coming from a Pascal string for instance you would use the second function CF string create with Pascal strength there are several other similar kinds of functions for the other types CF string create with file system representations you have screen create from data where you provide an encoding and so on for basic access you use the next two functions CF string get length return to the current length of the string CF string get character at index returns the character at the given index if you want more efficient processing you can get a bunch a range of characters at once using CF string get characters and if if you have a CF string and find that you need a Pascal string or some other type to communicate with another API you can get it with CF string get Pascal string only the last line there shows you how you create a constant CF string CF sir all caps and then the string within quotes will produce a constant CF string for your youth mutating some CF strings are mutable we'll talk more about that in a bit if you have immutable strings here are the basic functions you'll use CF string append append appends another string onto the bass string CF string replaced replaces a range of characters inside the current string with another string CF string insert performs a straight-up insertion and CF string trim is added here is an example of more complex functionality available CF string trim will take a trim string and compare it to the beginning and the end of the given string and strip it off however many times it may appear now I said that CF strings are becoming the way by which strings are communicated throughout the api's so here's an example of this if you look inside the carbon toolbox and some old API you may be familiar with set W title and get W title which set and get the title of a window after the introduction of core foundation the API below it has been introduced set window title with CF string copy window title as CF string which allows you to set the window title in a richer Unicode ready manner okay another basic type types inside of CF is CF data see if data is simply a way to get an object representation around an array of bytes it's more versatile than using a simple void store avoid star or a struct pointer because it's opaque and because it encapsulates the notion of length and there are a couple very basic accessors CF data get length and CF data get byte pointer I'm going to move on now to talk about collections there are a number of different collections inside of core foundation and by a collection I simply implement object which can hold other pointers and most of the time you're going to be holding other objects CF array and dictionary are by far the most common of the collections you would be using and array as you would expect holds an ordered list of values and a dictionary holds out values as key value pairs you give me the key i'll give you the value there and there are a number of left common collections also on the system set bad bag bitch vector binary heap tree are just a few of them there are actually several others as well so let's look at CF array a couple creation method CFRA create creates an immutable array you give me an array of values and the number there and i'll create an array around it CF array create mutable creates a mutable array and you will tell us the capacity and the callbacks we'll talk about that in a moment once you've got an array the basic API is the F array get count to find out how many objects are in the array and then CF array get value at index which will give you the value at the given index mutation CFRA insert value at index is is the most common mechanism CS dictionary you'll notice the naming between CF dictionary and CF array is very consistent CF dictionary create creates an immutable dictionary CF dictionary create mutable creates a mutable one CF dictionary getcount gives you the number of key value pairs currently stored in the dictionary get value you provide the key will give you the value back associated with that key and set value allows you to associate a value with a given key so now that we've looked at those basic api's let's talk about collections in more general terms all of our collections contain pointer sized values as I said most of the time you're going to be storing other objects but not always so how do you configure the behavior differently depending on what's being stored well that's what the callbacks are all about you pass the callbacks one to create when the collection is first created and the callbacks tell the object what to do as objects are being added and removed from the collection collections can also be created created either mutable or immutable and we'll go into into both callbacks and mutability and greater detail okay so as I said callbacks determine what the array or the dictionary is going to do as values are added or removed ninety percent of the time you're going to be storing other CF objects inside of the collection when that happens use the default callbacks we provide so for example KCF type array callbacks is the set of callbacks you use for an array that's going to store CF types as you would expect as objects are added to an array this set of callbacks will retain the objects on the way in release them on the way out of the remaining ten percent of the time nine percent of that is going to your collections are probably going to hold pointers that you just want to manage yourself you would rather the collection does not do any management for you when that's the case simply pass null at that point CFR ACF dictionary all the collections will simply take their hands off you give them you give it a pointer value it will hold the pointer value but it won't do anything with it once in a blue moon you will be trying you will be using CF array or CF dictionary to store a special data structure that has its own memory management scheme this is the point at which you're going to be writing your own call back you will have to add functions that define how the object is retained on the way into the collection how it should be released on the way out and then you will pass those callbacks to CF array or whatever collection you're using moving on to the mutability there are three kinds of mutability in the system an immutable object as you would expect you can change neither the content nor the size once the object has been created the data is going to remain constant until the object is destroyed a fixed size collection you can change the contents all you want as long as you do not exceed the given capacity and a fully mutable collection you can change the content and the size not all of the collections support all of the kinds of mutability both array and dictionary do when you're in doubt check the documentation the documentation clearly marked what kinds of mutability are supported by which collections and also I wanted to mention here although CF string and CF data are not themselves collections of other objects conceptually a string of the collection of characters and data is cool is a collection of bytes and therefore we use these mutability principles for both CF string and CF data as well and they also support all three types of mutability so the way it works is this when you call CF string creates the CF array create whatever you're going to get back a fully immutable object when you call CF array create mutable you will get back a mutable object if the specified capacity is greater than 0 that will be taken as the maximum capacity for your collection so CFRA create create mutable with a capacity of 10 produces an array that can never hold more than 10 objects on the other hand if you pass a capacity of 0 we will create a fully mutable object for you and the array or string or dictionary will automatically grow as new objects are added in so for example CF array create it's going to produce an immutable array you just provide the the objects that are going in and the number of them and there you go CS dictionary create mutable passing a capacity of 10 creates a mutable dictionary that can never contain more than 10 key value pairs CF string create mutable passing a capacity of 0 produces a fully fully mutable string of unlimited length and as strings and characters are added to the to this string it will grow to accommodate them so how does this all come together well given these basic pieces of strings datas arrays and dictionaries you can actually build up some very complex trees of objects you can also we also support several other types but string data array and dictionary form the core of them there are a couple restrictions first of all it has to be a true tree no loop so arrays can't include themselves dictionaries can't include or it can't include themselves secondly the keys of the dictionaries must always be strings and we create an abstraction on top of such a structure and call it a CF property list ref so why are property lists useful they're useful because we make them persistent they have a simple flattened XML representation and you can easily convert to and from that flattened XML representation expresses the data and the rich tree structure now we do not handle the file access part of this as a rule core foundation does not touch the file system so it's up to you to read and write the data to and from whatever file you're taking it from so why are the properties why does this make property list useful it's useful because property lists are very easy to program they're small they're very very flexible you know just if you need a new if you need to represent new data just hack another object onto the end of the array or create a new string and as I said they're persistent the API for persistency is very straightforward so if you ever find yourself needing a small flexible data format of some time try out CF property list see if it'll manage your needs the one caveat here is property lists are not useful as a general database it does not scale well and that's because XML is a serialized data representation so there's no ability to scan into the middle and locate an object out of the middle so for example if you look in Mac OS 10 where we use property lists ourselves you'll find them in small configuration files all over the place we use them to configure applications and provide much of the information that find your needs for instance when viewing an app package plugins use configuration files to announce their API as well as announcing how they fulfill the API there are a number of small system eunuch see kind of parameter configuration files that are that have been migrated to property lists we also use them for the user preferences on the system user preferences the classic example of where we don't know what information what information a given application needs to store but we do know that it's likely to be small and we do know that our types are likely to accommodate them the pasteboards property list provides a good flexible medium for communication on the pasteboard we use it there as well and this last point is one of my favorites so you need to deliver an application yesterday you might well prototype using property lists as your datastore that will at least save you the burden of figuring out how you're going to what your final data format is and we found it remarkably flexible for doing quick prototyping in fact the the original HTML rendering engine in the cocoa framework used properly lists entirely for its backing store so I mentioned there were some other property list types these are very simple object wrappers that you would rarely use except that you need to store a particular kind of value in a property list the three most common are listed here CF date wraps asst wraps a date or time CF number and CF boolean wrap simple numeric values and again we're not suggesting that you use this in place of a raw integer or a raw boolean rather when you find you need to store such a value in a property list these rappers are available to do that ok debugging and getting help I mentioned earlier that there is a debug library available inside of course foundation what the debug library adds is a number of extra assertions argument checking that kind of thing and what happens is as soon as one of those assertions finds an invalid argument it's going to log an error and abort your program that's going to make it much easier to isolate the problem find the change get a good back trace and we found that many of the most common programming errors in we see with core foundation can be caught this way so please run against the debug library as you develop core foundation code I've also put a list here of the most common errors in programming with core foundation passing null is CF type there's a classic one null is not a CF type it is not a valid argument to any of them any of the pseudo methods inside of core foundation another common error is releasing the return value of a get function you call CF array get value you never got a reference to the word the function includes the word get but you release it anyway well sooner or later that array is going to be destroyed or someone else is going to remove that value from the array at that point the array will release the object itself boom memory Smasher the other half of that equation is failing to retain the value that came back from a get function so once again you get a value out of CF array using CFRA get value you intend to keep that value pass the lifetime of the array you need to retain it if you do not when the array disappears so does your object okay so there you are in a debugging session you've got a CF type you don't know what it is and you're trying to figure out what's gone wrong you see us get type ID to determine the class of the object you've got you can compare that with CF typename get type ID so see a string get type ID returns the type ID for all strings yes array get type ID returns the type ID for all arrays CF show will print out any CF object to the console or wherever standard out happens to be in gdb you can invoke CF show directly from within a break point very useful for looking at what exactly has gotten into your string if you would rather get that that information into memory UCF copy description it will give you exactly the same output but stored in a CF string so you can if you want right it's a file look at it later whatever tracking memory problems that occur in the system CF get retain counts will always return the current reference count of an object you can use that to make sure that the reference count is incrementing or decrementing as you expect you can install a custom default allocator and use that to locate leaks and memory corruption and finally if you look on a vp for system there's an application in system developer applications called object Alec you can view you can run your program under object Alec and it will show you some of the CF types as they are allocated and destroyed all of the common ones are there if you have string or a dictionary all that kind of stuff finally there's a fair bit of documentation online you can find it in system developer documentation core foundation on the dt for CD it's also available on the web at developer.apple.com tech pubs core foundation there is some example code inside of system developer examples core foundation and the release notes are available in system developer documentation release notes corefoundation HTML you
