WWDC2000 Session 125
Transcript
Kind: captions
Language: en
ladies and gentlemen please welcome the
is right Mac os10 applications
technology manager welcome everybody
session 125 core foundation advanced so
after the last session I heard two
comments one developer said the stuff
was blowing him away and someone else
said they can't get the wait to get
their hands on it so I'm really pleased
to introduce more of it in this advanced
session so at this time please welcome
Becky will rich from the cocoa framework
team thank you David Wow well welcome
back so we're just going to continue
what we started talking about this
morning helps if you hold it right side
up just a little Keith I'm Becky will
rich still and what we're going to do
today in this afternoon is continue
where the core foundation basics picked
up so for those of you that maybe did
not make this morning's talk we're going
to repeat some of the initial parts
where we talked about where core
foundation lives inside of Mac OS 10 and
then we're going to move on and look at
some of the system the subsystems and
services that core foundation provides
so in particular we're going to be
looking at CF bundle and CF plug-in and
and what what they can do for you then
we're going to talk a little bit about
preferences and how CF can make it
easier for you to manage user
preferences in your application we're
going to look very briefly at what XML
services are provided and then finally
we're going to spend a moment talking
about advanced memory tricks that you
can use it when working with core
foundation as I mentioned in this
morning's talk corefoundation lives
right above the operating system layer
and at that layer we are very concerned
with performance because we impact most
everything that runs on the system
that's reflected in the api's and there
are a number of advanced tricks you can
use to reduce your memory footprint so
just to repeat what I said this morning
core foundation is the lingua franca on
Mac Mac os10 it is the language by which
you can communicate across both carbon
and
so those the same definition you saw
this morning a medium of communication
between peoples of different languages
and for us we're interested in
communicating between carbon and cocoa
so there is the architecture diagram for
Mac OS 10 and there we are inside the
core services layer the core services
layer remember is that layer where many
common common application needs are
provided that are below the graphics
layer so in particular you'll see the
file manager inside of there the alias
resource managers as well and beneath
all of that is core foundation providing
the basic types used throughout the
system so this morning we talked about
the basic data types in core foundation
strings arrays dictionaries and then
finally how it all came together is
property list now we're going to focus
on the second half of the equation the
non graphical services that core
foundation provides to all its clients
in particular we're going to look at
localization support as provided by CF
bundle and user preferences so what do I
mean when I talk about a CF service what
I'm talking about is an integrated sub
sub system that's built based on the CF
types that we saw this morning there are
several inside core foundation some of
which you are likely to never use
yourself CF run loop is an example
that's we use the run loop to maintain
the main event loop in both carbon and
Coco applications in all likelihood
you'll never need to use it but it's
silently doing its work inside of a
carbon application or a Coco application
others you will find yourself using
directly see a bundle is an example of
that so this this afternoon we're going
to be talking particularly about CF
bundle which you will use to get at the
different pieces inside your
applications package CF preferences
which you can use to store user
preferences see if preferences will do
the work of reading and writing to file
and creating the persistency format for
you
CF XML parser which if you're interested
in parsing XML files obviously will give
you a hand so with that I'm going to
turn the stage over to Doug Davidson my
colleague who's going to spend some time
talking about bundles in the app
packaging scheme Doug so I'm Doug
Davidson good afternoon I'm here to talk
to you about bundles what they are what
they do how to use them by the end of
this talk you should know what bundles
are and what they can do for you how to
use the CF bundle api's deal with them
and where to go to get more detailed
information about them so first of all
what is the bundle bundle is a way to
treat all of the files associated with
an executable as a single object now
once upon a time an application was a
single simple thing just an executable
file but applications need resources so
you add a resource for can you put
resources in there and you still have a
single file but applications have a way
of accumulating other files with them
additional executables libraries text
files quicktime content HTM all sorts of
stuff now it's Nicholas ten it gets even
worse because you might want to have
potentially different versions of this
stuff one for Michael is 8 9 14
michaelis 10 plus this is a multilingual
system which means if you would want to
have different versions of these some of
these things for the different languages
or language regions that your
applications look lies into so how are
you going to hold all this stuff the
answer is in a bundle now what can a
bundle whole first of all a bundle can
be wrapped around many different kinds
of executables application packages are
bundles frameworks are bundles they have
loadable bundles plugins can be bundled
and a bundle can contain multiple
executables
and it can potentially contain different
versions of these executables one for
mac OS 89 one from Michael 10 if you
like what else can a bundle hold it can
hold what we call bundle resources which
are just any kind of file based resource
these can be either localized or non
localized anything you want to put in
there quicktime content that interface
builder nibs anything you want and CF
bundle will then automatically look up
and retrieved for you the right version
of this resource based on the user's
language preferences in the platform
you're running on what else well of
course you have resource manager
resources as always and with bundles you
can have some of your resources that are
localized amnon localized potentially
but some that are localized and CF
bundle can load the correct version
according to the user's language
preferences what else metadata you can
store information about your bundle and
how it is configured in what we call the
info dictionary or info.plist this is an
XML property list particular dictionary
the keys can be arbitrary strings Apple
is defined a number that has special
significance easier to see a bundle
itself or to the finder but you can add
as many as you like and the values then
can be arbitrary property list types
what else can you put in a bundle well a
bundle is supposed to be self-contained
your application should be able to
contain everything it needs so you can
put subsidiary bundles libraries
frameworks etc inside the bundle or
basically just anything you want some
characteristics of bundles bundles are
cross-platform that means Michael s89
and Mac os10 anything in them can be
versioned one version for mac O's 891
version 4 10 they are multilingual you
can have different versions of your
resources
or particular languages of particular
language regions across binary on Mac
os10 we have both CFM and Marco binaries
and see a bundle will automatically know
the difference understand both and
automatically provide the glue to allow
you to call between them self-contained
movable reen amiable they're designed to
be a single object to the user so that
for example or install the teacher can
just be drag and drop in the finder or
you uninstall procedure just a
drag-and-drop rename them as long as the
internals are not touched the bundle to
not break and finally filesystem
independent that means the design so
that is not necessary to use resource
Forks so that these bundles can be moved
to file systems that may not have
support for different Forks so you could
store them on arbitrary file system of
arbitrary servers cd-rom etc and without
loss of fidelity and just drag and drop
from them or maybe you don't even need
to install maybe just launch it directly
from the server now i should say one
thing that bundles don't provide is they
don't provide a space for you to write
on if you have files that you need to
write out so it should probably go
somewhere else and one reason for this
is because your application might have
been launched from a server from the
cd-rom it's kind of hard to write to a
cd-rom the next section of this talk
nazia preferences will go into a little
more detail about possible places where
you can write out file
now I thought that probably the best way
to explain about fondles will be to just
show you one so we can get the demo to
hear I've made up the simple bundle this
this happens to be an application
package and i called it simple test and
so here's my install procedure known as
some copying to the desktop that's it
here's my own install procedure let's
see let's see that again okay now just
one thing is obvious i will launch it
double click on it and here's my
application okay but close i prefer to
work in french ok now i'm working in
french
here's my application in French well
maybe I prefer Japanese now one thing I
want you to notice is that this is not
just picking a single language this is a
preference order so suppose I prefer
italian my second choice is German than
French now I didn't actually localize
this application into Italian so when I
launch it when i get is my second choice
it's with german so now let's take a
look and see what's inside this model
now what I want to say is this is a
typical bundle layout but I don't want
you to pay too much attention to exactly
the details of where things are located
is there are several variations just
look at the various components and how
they work together see a bundle
understands all the variations past
present and future and will be looking
for you so what do we have first of all
we have are executable this is the
executable for mac OS 10 and there is
another version of the executable for
mac OS 8 and 9 called is labeled mackel
is classic what else do we have we have
the metadata that I talked about there's
a special file called packaging so just
hold to type and create our information
and then we have the info.plist which
altering so dictionary so I want to take
a special look at that and here that is
and i have set up a number of keys in
here i just want to point out some of
them CS fondle executable that is what
tells see a bundle what your primary
executable is for this bundle
and see a bundled name is the name of
the bunch and there are a number of
others lse see a bundle identifier this
is supposed to be a unique
identification string for your bundle
and we recommend that people use the
format that may be familiar from Java
which is calm dot your name up so forth
first Internet name so just so that
you'll get a unique string so each
bundle can be uniquely identified now
there are many possible teas that could
go in the dictionary and some of them
having significant see a bundle some of
them have significance to other things
like the finder there's going to be
another talk tomorrow i believe it is on
application packaging in particular
which we'll discuss in much more detail
what the finder wants to see and some of
these entries in the dictionary can be
localized themselves and i'll go into
that a little later so what else is
there in the bundle well we have the
resources and first of all let's take a
look at the non localized resources
those it don't depend on which language
using and simple tests are SRC this
contains the non localized resource
manager resources for this application
in the data fork of that file and there
is also another version of that simple
test matt goss classic which contains
the same thing but for mac OS 8 & 9 you
don't actually you don't have to have
that but if you have separate versions
you can have separate versions for
different platforms then I have an icon
and though maybe a movie anything you
want you can put in here now we also
have localized resources and these are
in separate folders for the seven
languages in language
regions so for english i have in
localized rsrc i have the localized
Resource Manager resources for this
application and and I have the simple
test nib which is one of interface
builder interface definitions and if you
haven't seen interface builder in action
you really should then I have info.plist
rings this is what contains the
localization for any of these items in
the info dictionary that need localizing
and localizable dot string which
contains localizations for other CS
Turing's done we give special attention
to the localization of CF strings
because the cs string is our basics
Unicode savvy internal at
nationalisation ready strength and so
it's the most common thing you want to
localize and then anything else that I
want to put in here and then you'll see
that the French versions you have French
versions of all these things-- and
german and japanese and so forth and see
if fondle automatically picks the right
one based on the user's language
preferences and on the platform there is
also another talk tomorrow afternoon
specifically on maccalister
immobilization which will go into this
in much more detail
now we could get their slice back on
so
now we just talked about bundles as I
live on the disk now what is the CF
bundle CF bundle is the programmatic
object that represents the bundle on the
disk to your application so you know
there's a bundle how do you create the
CF bundle that corresponds to it
canonical way to do so is simple you
take the URL the points for the bundles
location and pass it in to see up on
they'll create and you're going to see a
bundle if the code for the bundle is
already loaded and running in your
process then there are other ways to get
ahold of CF bundle for example the
bundle for the application itself is
called the main bundle and you see a
bundle get main bundle and it gives you
the main bundle no arguments if you have
some other bundle perhaps the framework
or a loadable bundle plug in and you
know that code is already loaded then
you can look it up by its identifier
remember the identifier with that unique
string that we talked about this is very
useful for example if you have a
framework a loadable bundle you don't
necessarily want to know exactly where
it's located on the disk but once it's
loaded inside its code you want to be
able to find its bundle so you look it
up by the identifier now then once you
have a CF bundle what can you do with it
well probably the most important most
common thing is to look up these bundle
resources again it's very simple see a
bundle copy resource URL you pass you in
the name the resource you want MCS on no
returns of a URL that points to it it
will look up the correct version based
on the user's language preference again
in the platform the nother thing you may
want what to do is to look at the
metadata it's on the info dictionary and
CF fun will get value for intra
dictionary key you pass in a key it
passes a lot of value correctly
localized if that particular value
happens to be localized and there's also
see a fund will get package info which
the type and creator that I mentioned in
the package info file what else can you
do is step one well as I mentioned you
can have resource manager resources and
so there is a nape EIC a bundle open
bundle resource files which simply opens
both the non-local odds and the
localized resource manager resource
files for that application now in case
of an application bundle you actually
don't need to call this it will be done
automatically for you or launch but if
you have some other kind of bundle
framework laudable bundle that had
resource manager resources in it you
might need to call this API yourself
explicitly and as I mentioned we give
special attention to the localization of
CF strings and so we have a number of
functions starting with CF copy
localized string to get the localization
to see a string out of files like the
localizable dot strings that I mentioned
what else can see a bundle do well
cieplo know can also load code and on
again it's very simple all you do is
tell your bundle load see a bundle load
executable and it loads the code see a
bundle automatically figures out on OS
10 whether the code it's the ephemera ma
co and uses the correct procedure loaded
of course 10 s 89 it's just the FM and
once you have the code loaded then you
can if you want to call into it and you
can look up functions by name and see a
bundle will return you a function
pointer and whether you're cup you are
calling from CFM amok oh and whether the
bundle you're loading is CFM bamako see
a bundle automatically figures out and
returns an appropriate function quarter
in either case you can use to call one
caveat though on DP floor if you are
calling this from CFM then an order for
it to work correctly you must have
turned on the
karbonn Ector libraries this is
described in the code fragment manager
release note on your CD in future this
will be available all the times everyone
okay now the next thing I wanted to talk
about is CF plugin if you're writing
plugins perhaps you have perhaps the
functionality I just talked about is
perfectly fine for you all you want to
do is be able to load load code and look
up functions by name or maybe you
already have your own plug-in model that
manages the interface between the
application of plug-in yourself in that
case you may not need to look at CS
plugin at all however if you are looking
for a sophisticated API for managing
interfaces between an application and
this plugins CF plugin maybe what you
want to use and there are a number of
apple projects which you may have heard
about in various other things that will
use the f plugin for their plugins and i
don't really have time to go into the
detail to see a plug-in right now this
one is briefly describe what it does the
application will describe the interfaces
that it was looking for and the plug-in
itself are advertised that information
in its info dictionary or it can also
register dynamically using the API and
then the application will then look at
the plug-in interrogated see if what
interfaces is support the interfaces are
looked up by uuid which is the universal
identifier and the interfaces are tables
and function pointers they are calm
compatible if you use calm in particular
we specify the I unknown interface we're
not using calm but they should be
compatible lay out there is an example
of this detail example in the CF bundle
mcf plug-in release note
and really this is something that is
best learn by example so now what I want
to reiterate is you take home is bundles
our way to treat all the files
associated with an executable as a
single object and CF bundle is the
programmatic interface that you will use
to deal with them so I'm going to turn
things back over to Becky thanks Doug
look simpler than what you're doing
today good that's the idea okay so I'm
going to go on now to talk about the
user preferences services that core
foundation provides and it provides its
vs CF preferences the idea was to give
you a mechanism for easily storing and
retrieving your user preferences without
forcing you to define your own files
your own file structure you give every
every preference a name then you assign
a value to that name the value can be
any of the property list types we talked
about this morning you can even make it
an array or a dictionary with complex
with a complex structure underneath and
then you hand it off to us and we handle
everything else and in particular the
data format and the storage is our
problem not yours you will always be
dealing with the CF type so the details
these are kind of internal
implementation details but i thought i'd
share them with you anyway we use xml
for most of the backing stores there are
a couple exceptions to that when in
particular when we have to share across
the network we cache preference values
for efficiency so that every time you
ask for a preference and every time you
write a preference we don't actually hit
the disk and CF preferences like all of
core foundation is a thread-safe system
the caveats CF preferences is not
intended for hundreds upon hundreds of
caves of data Doug mentioned that if
your application needs to write data it
should not go into the bundle you can
put it in preferences if it's of an
appropriate size in nature on the other
hand if you need to write hundreds of K
of data you have two solutions available
to you if it's a temporary cash write it
to the temporary folder if you need a
permanent storage mechanism you can
still use fine folder to find the
Preferences folder and write your own
data there that way however we are using
property list property lists or XML I
may have all the same serialization
problems I talked about this morning
their band is best used for under 100k
of data also CF preferences is not
intended for app critical data well what
do I mean by that most people consider
their preference is critical well I
simply mean that if it turns out that a
preference value is not in the
preferences file your app should not
crash okay likewise if someone has gone
in there and written a bad value your
app should not crash we guarantee when
we read the file that if the file itself
is corrupted will fail we will fail
gracefully and return null your job is
just to catch that and make sure that
you're not going to crash because we
couldn't we couldn't load your
preferences to the API is very simple
most clients are only ever going to need
these three functions CF preferences
copy app value will read a preference CF
preferences right app value will take a
preference value from you and write it
out and then see if preferences app
synchronizes what you use to synchronize
the cache with the permanent storage if
you call CF preferences app synchronized
every time you read or write a
preference then you know you've defeated
the cash the idea here is that you would
write several preferences at once and
then synchronize the cash or perhaps
even leave it to a lower library to do
the synchronization for you
so let's take a look at the three
functions in detail CF preferences copy
app value takes two arguments the first
one is the key or the name of the
preference you wish to retrieve and the
second the second argument is a string
which identifies your application this
is going to get a cod CF preferences to
go out and look at all the various
places that preferences are stored find
a match for the key and it's fine
assuming it's fine such a match it will
return the value the other half is
writings you have preferences set appt
value you supply the key the new value
and again your application ID once
you've written make sure that at some
point in the future you call CF
preferences app synchronize or you know
that a library is going to do you do it
for you this is mostly of interest for
cocoa applications the cocoa frameworks
will synchronize for you so what was
that application ID in the API most of
the time you're simply going to pass KCF
preferences current application and that
says this is this is a preference for
the current application UCF bundles
abilities to locate the correct place to
store this information in those cases
where you're writing code that needs to
write preferences to other locations the
apps are going to be identified by their
bundle identifier we chose the bundle
identifier because the bundle ID as Doug
mentioned is unique so as he showed you
the bundle ID should be set somewhere in
the info.plist under the CF bundle
identifier key and should be of the form
com company named Daphnis now if the f
preferences is asked to write a
preference for an application that has
not set this key see if preferences is
going to default back to using the
applications name itself but you know as
soon as you do that we run the risk of
conflicts and that's why we're
encouraging everyone to set the bundle
identifier okay so there are a handful
of convenience functions a lot of times
when you're reading a preference value
you just want a boolean value true false
other times you just need you need to
store an
value so that's what these two functions
are intended for see if preferences get
at boolean value and see if preferences
get app integer value in both of these
cases it returns the value that it finds
or if it can't find the value or the
values not of the proper type type they
default to different values you have
preferences get app boolean value is
going to return false get app integer
value is going to return 0 if you're
interested in the difference between a
genuine zero value and the the
preference not being properly set you
use the second is valid argument and we
will tell you whether we found a valid
preference or not CS preferences these
functions will go through and check for
several different possible formats so by
using CF preferences get at boolean
value we will not only check for a true
boo cf boolean type but also check for a
CF string that matches true or false for
instance and also check for some number
formats so where are these preferences
coming from I've mentioned a kind of
alluded a couple different times to the
fact that an application preferences
could come from several different
locations we call each of these
locations a domain and then we combine
all the different domains that are
relevant to a particular application
into what we call the search list and
when we look for a preference for your
application we're going to just walk the
search list in a fixed order until we
find what until we find the one we're
looking for or we fall off the bottom of
the list so what's the preference domain
a preference preference domain is
uniquely identified by three things the
user the host and the applications
identifier so I could for instance talk
about the male preferences for the user
Becky will rich on the host this
particular host but you can also simply
refer to each of these as either the
current or any so I can look for the
male preferences for the user Becky on
the current host or a search for
preferences set by by the mail
application for the user Becky
on any host if on a fully networked
environment so in all cases current
means the user host or application
relevant to the current process the user
who that's the user who ran the
application the application being run
and the host that the application is run
on any means that the preference was not
is not specific to a particular
application so for instance it's very
rare to want to write a preference for
an application that's specific to just
this host most of the time those
preference and preferences go to the any
host domains so just some examples the
preferences for the current user on any
host for the currently running
application is the most common domain
use this is where 90% of your
preferences are going to be stored maybe
ninety nine percent but you can have
other combinations for instance the
current user on any host for any any
application I might want to set a global
font preference in that domain for
instance I might also have an have
preference that pertains to any user on
this particular host for any application
so printer preferences might be an
example of that once those domains are
set here's where CF preferences look
this is the search list in general we
give preference to current settings over
any settings we consider the current
users preferences the most important and
we consider application preferences more
important than hosts so we start by
looking at the most specific domain the
current user for the current application
for the current host and move downwards
to the most general and you can see
we're going to search all of the crew
the current users default before looking
at the global user defaults when we
write preferences by default we're going
to write it to that most common domain I
was talking about this user this
application but not specific to any
particular host
so once in a while you find yourself in
a situation where you're writing four or
five different applications that need to
share preferences perhaps they're
sharing a library that defines some
common common functionality and there's
a preference unique to that library in
this in these cases you're going to want
to use the sweet preferences provided by
sea of preferences we consider the
applications that are going to share the
preferences to form the suite to do this
you'll need to simply choose an
identifier for your sweet usually if
you're using a shared library we
recommend that you use the bundles
identifier for that for that purpose and
then all the applications that link
against that library or that wish to
partake in the sweet simply add the
sweet preferences to their search list
they do this by calling CF preferences
add sweet preferences to app the first
argument is the app ID that's the
application to which the sweet
preferences will be added the second
argument is the sweet ID which which
tells us which sweet should be loaded
once this is done all queries to CF
preferences will search the sweet I the
air the sweet preferences as well when
you need to write sweet preferences
you'd use the same API you would write
an application preferences you simply
substitute the sweets ID for the
application ID once in a blue moon you
may find yourself needing to access a
specific domain without going through
the search list this should be an
incredibly rare occurrence in fact I
don't think any application needs to do
this except for an application like
preferences which matt in which itself
manages the full preferences database in
this case we have the same three kinds
of functions we have a read function or
write function and a synchronized
function however instead of specifying
the preference location simply by app ID
you're going to have to specify the full
triplet of username hostname application
name application ID I should say now
there's some caveats if you find
yourself doing this the first one is
that not all of the domains are
implemented in particular the defaults
for any user any hosts are not
implemented yet likewise on Mac OS 9 if
you have not installed the login window
or if you're not configured for multiple
users current user doesn't make any
sense the intention behind the low-level
API is is to fail gracefully under these
conditions and simply return null null
to you however you have to be prepared
for that on the other promise we make is
that the app functions always work and
properly take care of you of using only
those domains that are relevant
debugging preferences so you're an app
developer and something's gone wrong
there is a command-line tool on DP for
it's a default command that allows power
users to view and modify the Preferences
database directly as I said you run it
from the command line there are a number
of different options i'm not going to go
through them now but if you just go to
the command line that executes default
help you'll get the full details it's
got a lengthy usage statement there and
that's all I want to say about
preferences so I'm going to go on now to
spend a moment to talk about the XML
services provided inside of course
foundation there are basically three
levels of XML supports the first one
we've spent a fair bit of time talking
about already that's property lists the
second one is a handful of simple quick
parsing functions that parse XML to and
from XML trees and finally there's a
fine-tuned parsing API available through
CF XML parser so just a reminder of
property lists as any tree built from
the basic CF types I've listed them
again here array dictionary data and
string should handle 90
sense of your data on date number in
boolean make up the rest property lists
have a flattened XML representation and
there's a very easy API to convert back
and forth between the rich CF type tree
and the flat XML data if you're
interested in CF property list each for
details there's also documentation on
the web CF XML tree provides the next
level of support well what is a CF XML
tree a CF XML tree is a specialized form
of a CF tree where each node in addition
to just the basic tree structure stores
a CF xmlnode the CF xmlnode provides
information to you about the XML
structure itself so are you looking at a
tag are you looking at a comment is this
a data string so and what you find
yourself doing is to walk the tree
structure of the xml file use the CF
tree front the functions for cs3 get
parents cfq get get child count and so
on to examine the XML structure of a
particular node use CF xmlnode so from
the tree call CF XML tree get node that
will give you the node then the node API
can be used to extract the information
specific to that to the XML structure
the API looks like this just a couple
functions CF XML tree create from data
you pass it the allocator as with any
create functions XML data is the
flattened xml of the xml file just read
from disk or retrieved over the internet
or whatever source URL is the URL to use
in for any relative references inside
the XML data parse options has to do
with the different options available on
the parser and then the version this
last field is very important the version
number tells us which version of the API
is you're working with as well as what
version of XML you're working with we
can guarantee binary compatibility for a
fixed version number however as XML is
revved by the w3c
and as the standards change we expect to
bump the version numbers and extend the
API the other direction is to go from an
XML tree to an XML data here the
functions a little simpler you just pass
an alligator for where to create the
data from and the three in question we
walk the tree generate the XML and hand
it back to you alright so that's all
very well and good if you're if you are
happy with using the CF XML tree
structure to represent the XML however
since that can represent any XML file is
fairly generic also since we're parsing
the entire file and generating the
entire tree in one pass it can be very
memory expensive you've loaded the
entire file into data and then we've
duplicated that in constructing the tree
for for higher performing and more
customized behavior UCF XML parser CF
XML parser is callback based it's much
the same as shoot I'm blanking on the
standard names the fax parsers I think
there are a number of options available
for configuring the parser that that was
that parser option filled the that we
looked at in the earlier API just a word
of warning in DC for not all of the
options are implemented the
documentation has the full details and
is up to date as to what implemented in
DP for and what is not and that's as
much as I want to say on XML
I'm going to move on now to talk a
little bit about some of the advanced
memory tricks you can play with CF and
I'm going to focus on CF string for
those purposes the reason why i chose CF
string to focus on in this conversation
is well for several reasons first of all
it's the most common CF type if people
are you're going going to only use one
thing from core foundation it's probably
the string also it demonstrates many of
the different memory strategies that are
used throughout the system so once you
know how to use CF strings optimizations
the other API is should look very very
straightforward to you and finally
probably because it is the most common
type CF stirring supports the most
different kinds of memory optimizations
so let's start with the simplest things
you can do move towards immutable
whenever possible immutable strings use
the least amount of memory of any string
because we don't have to worry about the
extra overhead necessary to grow the
string right likewise fixed mutable uses
less than fully mutable secondly if
you're going to have to walk the entire
string fetch multiple characters at once
and you can do that using beget
characters API and simply pass a buffer
of characters similarly there's a
handful of functions that include the
word PTR pointer the pointer functions
ask that you check to see if the CF
string has the desired type on hand in
other words can you return this type to
me and OH of one without any memory
allocations without any work done now of
course if the answer is no we're going
to return null and you should be
prepared for that so you might well see
snippets of code like this CF string get
Pascal string pointer if we have it will
return it if not you need to check for
null and if so you need to allocate a
buffer for the for the Pascal string and
then call the other
um the sorry the other API CF string get
Pascal string passing in your buffer and
then we fill it a little more complex is
to use an inline buffer and this case is
useful when you're going to go over
sequin when you're going to walk the
entire length of the string or when
you're going to be moving around a lot
in a small area and then move forward
and look in another small area so when
in other words when your access is
either sequential or highly localized it
keeps the memory overhead down
considerably from either walking
character by character right from that
in from walking character by character
but still keeps the access very fast the
cfd in line buffers are all implemented
via inline functions and using these
functions the actual CF string that
provides the backing store from the
characters is only rarely accessed and
it looks like this create a CF string in
line buffer that's a that's a structure
that straight up see structure and you
can create it on the stack as long as
you know that you don't need to pass the
buffer out from the from its scope
initialize it with your CF string so you
give it to CF string in it in line
buffer give it the CF string in question
give it a pointer to the buffer you
allocated and then pass the range of
characters you're going to be interested
in looking at now when you need to fetch
a character instead of going to the CF
string go to be in line buffer CF string
get character from in line buffer passes
pointer to the buffer and the index of
the character in question beyond that
the most complex level of memory
management is the no copy function the
no copy functions create CF two strings
around your own storage so you are not
running into any memory copy overhead or
double data overhead when you do this
though you are transferring ownership of
the backing storage to CF string that
means you're going to tell CF string how
to free the buffer when you're done
um and if you're working with mutable
strings you'll also have to tell CF
string how to grow that buffer now using
this trick you can even use buffers
character buffers directly on the stack
but if you do that there are a couple
things you need to be very careful of
first of all obviously if you pass the
string outside of the scope of your
stack buffer and you're going to have a
memory exception right because the
buffers been blown away likewise if you
it's even within that even within the
buffer scope you pass the string down to
a function that then retains the string
for later use you're going to have the
same problem you're you're going to exit
the scope of your buffer this whoever it
was who retain the string thinks the
string is still good but it's not so it
looks like this CF string create with
characters no copy the first allocator
there KCF allocator default explains how
the string itself should be allocated
then you pass it a pointer to the
characters that you have my buffer you
pass it the length of the buffer and
then finally you pass the buffer
allocator this allocator is what the
string is going to use to manage the
memory of my buffer when the string is
freed buffer allocator is going to be
consulted on how to free the characters
if the buffer needs to grow buffer
allocator is going to be used to do that
so normally you're going to simply pass
my pass whatever allocator you use to
allocate my buffer in the first place on
the other hand if you don't want CF to
do any management / over the my buffer
memory pass KCF allocator null ok so
these these final slides are mostly a
repeat from the from this morning where
you can go to get help there's a lot of
documentation online it's available on
the DP for CD of system developer
documentation corefoundation it's
available on the web at developer apple
com tech pubs core foundation example
code and system developer examples
course
foundation release notes system
developer documentation release notes
core foundation HTML there's a little
additional information for bundle
services however inside the release
notes directory you will find several
different documents of interest CF
bundle MCS plug-in provides sample code
on how you would use CF bundle and CF
plugin to create a plug-in model
info.plist describes the keys that we
define inside the the bundles
information p list that's where we
configured all the finder information
for the app package and localization dot
HTML provides information on how to use
the app packaging model to localize your
app as simply and effectively as
possible here are some of the other
talks that you might be interested in
core foundation basics already happened
hopefully you all had a chance to see
that carbon low level is Friday and you
can see some of the other the other
pieces that comprise that core services
level the app packaging and document
typing talk is going to go into the
details of just exactly what the
structure inside the app package is the
localization talk will give you the
details on how to go about localizing
your app and then the localization tools
talk will get tell you about the tools
available on the system to help you with
that oh yes one more thing who to
contact David Wright is our technology
manager he's the gentleman who
introduced me and he'll be coming back
up for the QA and we also have an
external feedback list CF hyphen
feedback at apple.com will reach all of
the developers involved in core
foundation and now I'm going to go