If I can chip in? I'm more of a THINK C person (version 5), so I'm fairly familiar with it. There is one good reason to use NewPtr, when it's a fixed block of memory you know will never get deallocated. You allocate it at the beginning and then just leave it there. It's a bit faster and less error-prone to access and the garbage collector won't have to work around it.
A Handle, as I guess you know is a pointer to a pointer. That means that instead of e.g.
C:
typedef struct {
char iName[256];
int iAge, iZipCode;
}tMyInfo;
... later...
tMyInfo *gInfo;
gInfo=(tMyInfo *)NewPtr(sizeof(tMyInfo));
... later....
DrawString(gInfo->iName);
You'd end up doing:
C:
typedef struct {
char iName[256];
int iAge, iZipCode;
}tMyInfo;
... later...
tMyInfo **gInfo;
gInfo=(tMyInfo **)NewHandle(sizeof(tMyInfo));
... later....
HLock(gInfo); // lock the handle first.
DrawString((*gInfo)->iName);
HUnlock(gInfo); // unlock when finished
So everything gets a bit more complex then. If you use a QuickDraw routine on a handle, you'll need to lock it first, - lock it because many routines move memory, so you need to prevent that from happening. And if early Mac OS can't move memory it can generate out-of-memory errors just like for NewPtr. Also Locking and Unlocking isn't reference counted or some other garbage collection technique. Instead there's just a single global lock per handle. Also, you should allow handles to be purgeable when possible, so that Mac OS can free their memory. Also, it's common practice to HMoveHi(
aHandle) when possible too, to make the garbage collector more efficient.
Lots of rules. But, I do actually like handles, they're a clever technique for coping with low-memory computers. They'd be a really good technique to apply to lots of IOT oriented MCUs which have a lot of the same kinds of constraints (on MCUs I tend to statically allocate so I can be sure that I don't get memory allocation failures).