Iphone 如何在Objective-C中使用局部静态对象?

Iphone 如何在Objective-C中使用局部静态对象?,iphone,objective-c,ios,Iphone,Objective C,Ios,如何在Objective-C中使用局部静态对象 - (void)foo { static NSMutableArray *mutableArr = nil; // initialize mutableArr somehow somewhere // using mutableArr several times } 如果使用静态变量。这是检查它是否在初始化变量之前初始化的好方法。如果使用静态变量。这是检查它是否在初始化变量之前初始化的好方法。我希望我没有遗漏任何东西,但

如何在Objective-C中使用局部静态对象

- (void)foo {
    static NSMutableArray *mutableArr = nil;
    // initialize mutableArr somehow somewhere 
    // using mutableArr several times
}

如果使用静态变量。这是检查它是否在初始化变量之前初始化的好方法。

如果使用静态变量。这是检查它是否在初始化变量之前初始化的好方法。

我希望我没有遗漏任何东西,但我就是这样使用它的:

- (void)foo {
    static NSMutableArray *mutableArr = nil;
    if (mutableArr == nil) {
        mutableArr = [[NSMutableArray alloc] init...];
        // add more first time initialization as required
    }
    assert(mutableArr);
    // now, use mutableArr freely...
}

我希望我没有遗漏任何东西,但我就是这样使用它的:

- (void)foo {
    static NSMutableArray *mutableArr = nil;
    if (mutableArr == nil) {
        mutableArr = [[NSMutableArray alloc] init...];
        // add more first time initialization as required
    }
    assert(mutableArr);
    // now, use mutableArr freely...
}

如果你的目标仅仅是拥有一个独生子女,那么现在这似乎是一个普遍接受的模式,如下所示:

#import <dispatch/dispatch.h>

+ (NSMyObjectType*)sharedMyObject
{
    static dispatch_once_t pred;
    static NSMyObjectType* sValue;
    dispatch_once(&pred, ^{ sValue = [[NSMyObjectType alloc] init]; } );
    return sValue;
}
通过同步对实际底层可变对象的访问和变异,并将整个集合作为不可变副本出售,可以为多线程并发访问提供安全性(尽管需要注意的是,通过创建不可变副本,消费者可以保留过时的副本,本质上,每个不可变副本从创建之时起就应该被认为是过时的。)

FWIW,有一百万种不同的方法可以做到这一点——我并不是说这种方法对每一种(甚至任何场景)都是完美的。但是依赖API的使用者为您提供锁定是一种灾难


综上所述,假设您只允许单线程访问,那么接受的答案是可以的。如果您只希望从主线程(可能在UIKit上下文中)使用它,那么您可以使用接受的答案,尽管我可能建议断言
[NSThread isMainThread]
这样,如果以后有人开始从后台线程调用您的共享访问器,您会很早失败。

如果您的目标只是拥有一个单例,那么现在这似乎是一种常见的、可接受的模式,如下所示:

#import <dispatch/dispatch.h>

+ (NSMyObjectType*)sharedMyObject
{
    static dispatch_once_t pred;
    static NSMyObjectType* sValue;
    dispatch_once(&pred, ^{ sValue = [[NSMyObjectType alloc] init]; } );
    return sValue;
}
通过同步对实际底层可变对象的访问和变异,并将整个集合作为不可变副本出售,可以为多线程并发访问提供安全性(尽管需要注意的是,通过创建不可变副本,消费者可以保留过时的副本,本质上,每个不可变副本从创建之时起就应该被认为是过时的。)

FWIW,有一百万种不同的方法可以做到这一点——我并不是说这种方法对每一种(甚至任何场景)都是完美的。但是依赖API的使用者为您提供锁定是一种灾难


综上所述,假设您只允许单线程访问,那么接受的答案是可以的。如果您只希望从主线程(可能在UIKit上下文中)使用它,那么您可以使用接受的答案,尽管我可能建议断言
[NSThread isMainThread]
这样,如果以后有人从后台线程调用您的共享访问器,您就可以提前失败。

@KevinBallard是的,我认为Objective-C可能支持这一点。@KevinBallard在C中,您不必关心引用计数。在这里,我必须保留计数,并在某个时候释放它。我想知道是否有一种简单的方法可以做到这一点。@Nickolas:静态变量存在于程序的生命周期中。如果希望对象具有普通对象的生命周期,为什么要使用静态变量?我想我缺少了一些您所设想的用法。@Chuck您是对的,简单地保留计数将是正确的解决方案。我现在对静态变量有了更好的理解。谢谢。我想接受你的评论作为答案。@KevinBallard是的,我认为Objective-C可能支持这一点。@KevinBallard在C中,你不必关心引用计数。在这里,我必须保留计数并在某个时候释放它。我想知道是否有一种简单的方法可以做到这一点。@Nickolas:在程序的生命周期中存在静态变量。为什么如果你想让对象有一个普通的对象寿命,你是否使用了静态变量?我想我缺少了一些关于你所设想的用途的东西。@Chuck你是对的,简单地保留计数将是正确的解决方案。我现在对静态变量有了更好的理解。谢谢。我想接受你的评论作为答案。FWIW,这不是第多线程并发访问的读安全性。也就是说,如果您要出售对单个可变数据结构的共享引用,那么您已经将线程安全性作为此方法的所有不同调用方的工作。FWIW,这对于多线程并发访问不是线程安全的。也就是说,如果您要出售共享引用对于单个可变数据结构,您已经使线程安全成为该方法所有不同调用方的工作。