The code in your question was originally
- (NSArray *)odds
{
static NSMutableArray *odds = [[NSMutableArray alloc] init];
// ... fill array ...
return odds;
}
and you said in a (now deleted) comment that you found that code in a Big Nerd Ranch Guide.
Well, that guide has an error then.
A static local variable exists for the lifetime of the program, but is only visible
inside the function where it is declared. The value of the variable is retained between
repeated function calls.
In C and Objective-C, a static local variable can only be initialized with a compile-time
constant, therefore
static NSMutableArray *odds = [[NSMutableArray alloc] init];
is invalid. (Btw, that restriction does not exist in C++. Therefore the above code is valid in Objective-C++, although pointless.)
So how to fix this? Method 1: (The simplest solution.) Drop the static
:
- (NSArray *)odds
{
NSMutableArray *odds = [[NSMutableArray alloc] init];
// ... fill array ...
return odds;
}
Now odds
is a normal local variable, and the array is created and filled each time
when the function is called.
Method 2: A static variable can be used to create and fill the array only once, when the method is called the first time.
That would look like:
- (NSArray *)odds
{
static NSMutableArray *odds = nil;
if (odds == nil) { // Check if array has already been initialized or not.
odds = [[NSMutableArray alloc] init];
// ... fill array ...
}
return odds;
}
The function “remembers” the value of the variable, so when the function is called the
second time, it returns the existing array and does not create a new one.
Method 3: The “modern” way to initialize something only once is to use the GCD function dispatch_once()
:
- (NSArray *)odds
{
static NSMutableArray *odds;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
odds = [[NSMutableArray alloc] init];
// ... fill array ...
});
return odds;
}
This has the additional advantage of being thread-safe.
2
solved meaning of Static NSMutableArray and multi thread usage [closed]