[comp.sys.mac.programmer] Another toolbox gotcha

amanda@lts.UUCP (Amanda Walker) (04/21/89)

This one isn't exactly a gotcha, but it is amusing enough that I thought
I'd add it to the Toolbox War Stories :-).

Rule: Always remove a resource before you replace it with something else.

History: I had written a couple little routines that maintained a settings
file, which had about three resources in it.  To avoid leaving the
resource file open for the life of the program, the "read" routine
did a bunch of GetResources, detached the handles, and closed the resource
file.  The "write" routine opened the resource file, did a bunch of
AddResources, and closed it.  Seemed pretty simple.

There's this note under "AddResource" that says you should make sure that
another resource with the same ID.  My mistake was in reading this as
advice instead of literal truth.  As it happens, the Resource Manager
will quite happily give you as many resources with the same type and ID
as you ask for, and "GetResource" will only find the first one, since
it's the first in the resource map...  The only way to access the others
is to either give them different names or to access them as the nth resource
of the given type instead of by ID.

I discovered this when my settings file had grown to 150K...

tim@hoptoad.uucp (Tim Maroney) (04/22/89)

In article <20-Apr-89.152339@192.41.214.2> amanda@lts.UUCP (Amanda Walker)
writes:
>Rule: Always remove a resource before you replace it with something else.
>
>History: I had written a couple little routines that maintained a settings
>file, which had about three resources in it.
>
>There's this note under "AddResource" that says you should make sure that
>another resource with the same ID.  My mistake was in reading this as
>advice instead of literal truth.  As it happens, the Resource Manager
>will quite happily give you as many resources with the same type and ID
>as you ask for, and "GetResource" will only find the first one, since
>it's the first in the resource map...

Generally good advice, but I believe it's even more efficient to simply
change the existing resource, rather than remove it then add a new
copy.  There's less rearrangement of the resource map involved.  Not
only is there a time penalty for adding and deleting resource map
entries, it may well require resizing handles used to store the
resource map information, which could potentially lead to problems for
a large resource file or a situation where little free RAM remains.
(It shouldn't, since all you're doing is shrinking it then growing it
back out to the same size, but it's best to be cautious.  For instance,
your program gets executed between shrinking and growing, and it could
inadvertently put a locked block into the "free tail" of the old
resource map.)

However, as a recent Tech Note points out, don't call ChangedResource
over and over without updating the resource file.  Due to a system bug,
the file will grow every time you call ChangedResource, and only be
restored to its proper size when you call UpdateResFile (or close the
resource file).  This isn't relevant to your situation, Amanda, since
you close the file right away after changes, but a lot of us do leave
our application preferences files always open.  (Why not?)
-- 
Tim Maroney, Consultant, Eclectic Software, sun!hoptoad!tim
"God must be a Boogie Man." -- Joni Mitchell