为 Xcode 4 创建/使用单例 NSMutableArray 的正确方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8931742/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 23:02:32  来源:igfitidea点击:

Correct way to create/use a Singleton NSMutableArray for Xcode 4

iphoneobjective-cxcode

提问by wayneh

I've reviewed (and tried) a bunch of the threads here regarding Singletons and NSMutableArrays. I'm new to Objective-C so please bear with me.

我已经(并尝试)了这里的一堆关于 Singletons 和 NSMutableArrays 的线程。我是 Objective-C 的新手,所以请耐心等待。

I simply want to create a few arrays that can be accessed from any view/.m file.

我只是想创建一些可以从任何 view/.m 文件访问的数组。

What is the best (or most concise) coding for a Singleton?

单例的最佳(或最简洁)编码是什么?

Below is what I have now and I get 1 warning at .m '@implementation' - "Incomplete implementation" 1 error at usage in a view .m file - "initializer element is not a compile-time constant"

下面是我现在所拥有的,我在 .m '@implementation' 处收到 1 个警告-“不完整的实现”在视图 .m 文件中使用时出现 1 个错误-“初始值设定项元素不是编译时常量”

This is the code I have now - my GlobalData.h file:

这是我现在拥有的代码 - 我的 GlobalData.h 文件:

#import <Foundation/Foundation.h>

@interface GlobalData : NSObject {    
    NSMutableArray *listOfHeadings;
    NSMutableArray *listOfItems1;
    NSMutableArray *listOfItems2;
}    
@property(nonatomic,retain)NSMutableArray *listOfHeadings;
@property(nonatomic,retain)NSMutableArray *listOfItems1; 
@property(nonatomic,retain)NSMutableArray *listOfItems2; 
+(GlobalData*)getInstance;  
@end

My GlobalData.m file:

我的 GlobalData.m 文件:

#import "GlobalData.h"

@implementation GlobalData
@synthesize listOfHeadings;
@synthesize listOfItems1;
@synthesize listOfItems2;
static GlobalData *instance=nil; 

+(GlobalData *)getInstance    
{    
    @synchronized(self)    
    {    
        if(instance==nil)    
        {    
            instance= [GlobalData new];    
        }    
    }    
    return instance;    
}    
@end

And in a view .m file (simplified):

在视图 .m 文件中(简化):

#import GlobalData.h

GlobalData *globDat=[GlobalData getInstance]; //error occurs here

Can someone point out the trouble and if there's better coding, please enlighten me - thanks!

有人可以指出问题,如果有更好的编码,请赐教 - 谢谢!

EDIT

编辑

Here's a few links I've tried to use:

这是我尝试使用的一些链接:

Can i have a single NSMutableArray in my multiple views application?

我的多视图应用程序中可以有一个 NSMutableArray 吗?

iPhone help with singleton class

iPhone 帮助单例类

回答by dtuckernet

In this case, you might be doing more than you have to. Granted this certainly isn't always the best solution - but you can put your NSMutableArray as a property in your App Delegate and then easily refer to it from any view. By doing it this way - you aren't locking it in as a 'singleton' but there is a 'singleton instance' of it (this helps a great deal for testability).

在这种情况下,您可能会做更多的事情。当然,这当然并不总是最好的解决方案 - 但您可以将 NSMutableArray 作为属性放在您的 App Delegate 中,然后从任何视图轻松引用它。通过这样做 - 您不会将其锁定为“单例”,而是有一个“单例实例”(这对可测试性有很大帮助)。

I have simplified this process here:

我在这里简化了这个过程:

YourAppDelegate.h

YourAppDelegate.h

@property (nonatomic,retain) NSMutableArray *myArray;

YourAppDelegate.m

YourAppDelegate.m

@synthesize myArray;

YourViewController.m

YourViewController.m

YourAppDelegate *appDelegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
NSMutableArray *myArrayFromAppDelegate = appDelegate.myArray;

From this point - you can do any manipulation on this value.

从这一点来看 - 您可以对该值进行任何操作。

回答by Kendall Helmstetter Gelner

Here's the "modern" version of a single method to turn any class into a Singleton (in this case formatted as a code snippet). It works in iOS4.x or higher:

这是将任何类转换为 Singleton 的单一方法的“现代”版本(在本例中格式化为代码片段)。它适用于 iOS4.x 或更高版本:

+(<#SingletonClassName#> *) sharedInstance 
{
    static <#SingletonClassName#> *_sharedClient = nil;

    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _sharedClient = [[self alloc] init];
    });

    return _sharedClient;
}

But, do you really need a singleton of a single NSMutableArray? You could use the built-on singleton - your application delegate, which is got to by calling:

但是,您真的需要单个 NSMutableArray 的单例吗?您可以使用内置单例 - 您的应用程序委托,通过调用:

MyAppDelegate * appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.myMutableArray addObject:...];

回答by rob mayoff

The error initializer element is not a compile-time constantis not related to how you create your singleton. The error is how you are accessingyour singleton. You are doing this outside of a function:

该错误initializer element is not a compile-time constant与您创建单例的方式无关。错误在于您如何访问单身人士。您是在函数之外执行此操作:

GlobalData *globDat=[GlobalData getInstance];

This means that you are trying to initialize a global variable (globDat) as the value of the expression [GlobalData getInstance]. You can only initialize global variables to expressions that are "compile-time constants". That means things like 0or "fred"or 8/2. The value of [GlobalData getInstance]cannot be computed at compile-time, so it cannot be used to initialize the global variable.

这意味着您正在尝试将全局变量 ( globDat)初始化为表达式的值[GlobalData getInstance]。您只能将全局变量初始化为“编译时常量”的表达式。这意味着一些事情,如0"fred"8/2。的值[GlobalData getInstance]无法在编译时计算,因此不能用于初始化全局变量。

Instead, you need to just use [GlobalData getInstance]inside your function bodies wherever you are currently trying to use the globDatvariable.

相反,您只需要[GlobalData getInstance]在您当前尝试使用globDat变量的任何地方在函数体内使用。

As for the warning, Incomplete implementation, I don't see what's missing. Perhaps you didn't post all of the code from GlobalData.h. Anyway, you should be able to click the warning (where it appears on the right side of the editor window) and have Xcode show you what's missing.

至于警告,Incomplete implementation我看不出有什么遗漏。也许您没有从GlobalData.h. 无论如何,您应该能够单击警告(它出现在编辑器窗口右侧的位置)并让 Xcode 显示您缺少什么。

回答by Giuseppe Garassino

This is the way I create my Singleton:

这是我创建单身人士的方式:

Singleton.h

单例.h

#import <Foundation/Foundation.h>

@interface Singleton : NSObject {
    NSMutableArray *firstMutableArray;
    NSMutableArray *secondMutableArray;
}

@property (nonatomic, retain) NSMutableArray *firstMutableArray;
@property (nonatomic, retain) NSMutableArray *secondMutableArray;

+ (id)sharedSingleton;

@end

Sigleton.m

西格尔顿.m

#import "Singleton.h"

static Singleton *sharedMySingleton = nil;

@implementation Singleton

@synthesize firstMutableArray;
@synthesize secondMutableArray;

#pragma mark Singleton Methods

+ (id)sharedSingleton {
    @synchronized(self) {
    if (sharedMySingleton == nil) {
        sharedMySingleton = [[super allocWithZone:NULL] init];
    }
    return sharedMySingleton;
}

+ (id)allocWithZone:(NSZone *)zone {
    return [[self sharedSingleton] retain];
}

- (id)copyWithZone:(NSZone *)zone {
    return self;
}

- (id)retain {
    return self;
}

- (unsigned)retainCount {
    return UINT_MAX;
}

- (oneway void)release {
    // Never release
}

- (id)autorelease {
    return self;
}

- (id)init {
    if (self = [super init]) {
        firstMutableArray = [[NSMutableArray alloc] initWithObjects:nil];
        secondMutableArray = [[NSMutableArray alloc] initWithObjects:nil];
    }
    return self;
}

- (void)dealloc {
    [firstMutableArray release];
    [secondMutableArray release];
    [super dealloc];
}

@end

Then, when you want to call your Singleton:

然后,当你想调用你的单身人士时:

#import "Singleton.h"

Singleton *singleton = [Singleton sharedSingleton];
singleton.firstMutableArray = ...
singleton.secondMutableArray = ...