How to initialize constant member C array in an Objective-C class?
how can I create a constant C array member in an Objective-C class? The lifecycle should be limited to the classes lifecycle and I don't want to use malloc.
At the moment I'm doing this:
@interface Bla
{
int myArray[3];
}
@implementation Bla
{
-(id)init
{
myArray[1] = 5;
myArray[2] = 6;
myArray[3] = 7;
return self;
}
}
But I want it constant and initialize it dir开发者_开发问答ectly, like:
@interface Bla
{
const int myArray[3];
}
@implementation Bla
{
-(id)init
{
myArray[] = { 5, 6, 7 };
return self;
}
}
you could take the C approach and use a constant array in your .m:
static const int myArray[3] = { 5, 6, 7 };
the lifetime of this array is the duration of the program, and it does not require malloc or storage per instance.
otherwise, there is really no such thing as a constant value for an objc type's variables (unless you are content with immutable zeroed memory). the best you can do is to make the ivar private and not provide a setter. a const ivar doesn't have much applicability either, since there are few optimizations the compiler could make in this case. of course, you could cast away constness, but that is a bad idea.
one final alternative: you can use a c++ instance which is created using its default constructor.
otherwise, you will have to use a dynamic allocation to create a dynamically populated const member variable.
Just as a convention, you shouldn't put curly braces around @implementation. About your question: the problem I see with the way you're trying to assign you array has the following error:
When you initialize a new ObjC instance of an object, its instance variables are set to zero, so your array will be a[0] == a[1] == a[2] == 0. This is because the allocator will ask for heap memory the size of your object + its ancestors. But later in the code, you're trying to copy memory from the stack to the heap: the { 4, 5, 6} array is created on the stack, and array[] lives on the heap. Do you see the problem here? What I would do, if you insist in doing it this way would be the following:
// compile from command line with
// gcc -framework Foundation -g -Wall -o test test.m
//
#import <Foundation/Foundation.h>
@interface Bla : NSObject
{
int array[3];
}
- (void)checkArray;
@end
@implementation Bla
- (id)init
{
self = [super init];
if (self) {
// init here
int tmpArray[3] = { 4, 5, 6};
memcpy(array, tmpArray, 3 * sizeof(int));
}
return self;
}
- (void)checkArray
{
NSAssert(array[0] == 4, @"invalid array initialization (4)");
NSAssert(array[1] == 5, @"invalid array initialization (5)");
NSAssert(array[2] == 6, @"invalid array initialization (6)");
}
@end
int main() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
{
Bla *bla = [[Bla alloc] init];
[bla checkArray];
NSLog(@"done");
[bla release];
}
[pool release];
return 0;
}
It's not the best way, and probably you want to stick to using malloc, but this way you won't have to free the array later. Also, keep in mind that doing it this way you won't be able to change the size of array[], doing so will get in trouble for sure :)
精彩评论