Re: Method with +
Re: Method with +
- Subject: Re: Method with +
- From: "Pierce T. Wetter III" <email@hidden>
- Date: Fri, 19 May 2006 17:36:37 -0700
From: email@hidden
Subject: Re: Method with +
Date: May 19, 2006 5:27:30 PM MST
To: email@hidden
Cc: email@hidden, email@hidden
BOOL *par = [MyClass GetParametersList];
// in the class MyClass
+ (BOOL*)GetParametersList
{
BOOL *parList = calloc(kTotTimeParam, sizeof(BOOL));
int i;
for(i = 0; i < kTotTimeParam; i++){
parList[i] = (i >= kTimeGenPosX && i <= kTimeGenVolu);
}
return parList;
}
You have allocated a chunk of memory. You are responsible for
freeing it.
Let's see if I can do this in a fashion worthy of Mmalcom, but with
my own "teach the idiom" twist.
To work within the idiom:
1. GetParametersList should have "alloc", "copy" or "new"
somewhere in the name to indicate that it returns allocated memory.
See: http://developer.apple.com/documentation/Cocoa/Conceptual/
MemoryMgmt/Tasks/MemoryManagementRules.html#//apple_ref/doc/uid/20000994
So "GetNewParametersList" might be a better name.
2. In Cocoa/ObjC is the idiom is that if "you" allocate something,
either "you" are responsible for deallocating it, or "you" should
return an autoreleased object.
In this case, "you" probably means "local to the MyClass" code.
The documentation states this in reverse:
A body of code should never be concerned with disposing of something
it did not create.
See: http://developer.apple.com/documentation/Cocoa/Conceptual/
MemoryMgmt/Concepts/ObjectOwnership.html#//apple_ref/doc/uid/20000043-
BEHDEDDB
The fundamental principle really being that you shouldn't have to
open the source code for a class or read the documentation in order
to tell whether you have to free/release something. I call this the
"one file open at a time" rule.
3. In practice, most people structure their code as follows:
a. If "GetParametersList" is only used inside "MyClass", it
could just as easily be turned into a plain C utility function:
static BOOL *GetParametersList()
{
BOOL *parList = calloc(kTotTimeParam, sizeof(BOOL));
int i;
for(i = 0; i < kTotTimeParam; i++){
parList[i] = (i >= kTimeGenPosX && i <= kTimeGenVolu);
}
return parList;
}
By structuring it as regular C and marking it static, you localize
it to the MyClass.m file. At that point, its perfectly reasonable for
the MyClass.m code to know that it needs to do:
BOOL *par = GetParametersList();
// do stuff
free(par);
Because by using a regular C call, you're _switching idioms_, so
that the code has to operate by C rules instead of ObjC rules. Since
the code is local to MyClass.m it also satisfies my "one file open at
a time" rule.
b. Alternatively, if GetParametersList is consumed _outside_ of
MyClass, then MyClass should return some sort of autoreleased ObjC
object instead as Eric Long wrote. Its very rare to have an ObjC
object return some sort of plain pointer, because C pointers don't
understand release/autorelease.
c. Finally, if you MUST return a C-pointer to code non-local to
MyClass, export a C-interface instead of an Objective-C:
BOOL *GetParametersListCopy()
{
return [MyClass GetParametersListCopy];
}
It's a small thing, but forcing people to use the C interface tells
them you're using C/C++ rules, which generally require you to free
everything once you're done with it, doesn't allow reference
counting, etc.
d. One case where it is generally acceptable to return a plain C
pointer is where the client code doesn't have to worry about
deallocating it. For instance [NSData bytes] returns a plain C
pointer, and there are some other methods on other classes. In that
case its ok, because the client code doesn't have to deallocate
something it didn't allocate.
Pierce
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden