静态NSMutableArray和多线程用法的含义

Had*_*adi -6 objective-c

static以下代码究竟做了什么,何时应该或更好地使用Static:

// Returns an array of 30 odd numbers
- (NSArray *)odds
{
static NSMutableArray *odds;
odds = [[NSMutableArray alloc] init];
int i = 1;
while ([odds count] < 30) {
[odds addObject:[NSNumber numberWithInt:i]];
i += 2;
}
return odds;
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*n R 8

你问题中的代码最初是

- (NSArray *)odds
{
    static NSMutableArray *odds = [[NSMutableArray alloc] init];
    // ... fill array ...
    return odds;
}
Run Code Online (Sandbox Code Playgroud)

并且您在(现已删除)评论中说,您在"大书呆子牧场指南"中找到了该代码.

好吧,那个指南有一个错误.

程序生命周期中存在一个静态局部变量,但只能在声明它的函数内部看到.在重复的函数调用之间保留变量的值.

在C和Objective-C中,静态局部变量只能用编译时常量初始化

static NSMutableArray *odds = [[NSMutableArray alloc] init];
Run Code Online (Sandbox Code Playgroud)

无效的.(顺便说一下,C++中不存在这种限制.因此,上述代码在Objective-C++中有效,尽管没有意义.)

那么如何解决这个问题呢?方法1 :(最简单的解决方案.)删除static:

- (NSArray *)odds
{
    NSMutableArray *odds = [[NSMutableArray alloc] init];
    // ... fill array ...
    return odds;
}
Run Code Online (Sandbox Code Playgroud)

现在odds是一个普通的局部变量,每次调用函数时都会创建并填充数组.

方法2:当第一次调用该方法时,静态变量只能用于创建和填充数组一次.那看起来像是:

- (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;
}
Run Code Online (Sandbox Code Playgroud)

函数"记住"变量的值,因此当第二次调用该函数时,它将返回现有数组,而不会创建新数组.

方法3:仅初始化一次的"现代"方法是使用GCD功能dispatch_once():

- (NSArray *)odds
{
    static NSMutableArray *odds;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        odds = [[NSMutableArray alloc] init];
        // ... fill array ...
    });
    return odds;
}
Run Code Online (Sandbox Code Playgroud)

这具有线程安全的额外优点.