Iphone 为Xcode 4创建/使用Singleton NSMutableArray的正确方法

Iphone 为Xcode 4创建/使用Singleton NSMutableArray的正确方法,iphone,objective-c,xcode,Iphone,Objective C,Xcode,我在这里回顾(并尝试)了一些关于单例和NSMutableArray的线程。我不熟悉Objective-C,所以请容忍我 我只想创建几个可以从任何view/.m文件访问的数组 对于单身汉来说,什么是最好(或最简洁)的编码 下面是我现在拥有的和我得到的 在.m'@implementation'处出现1条警告-“未完成执行” 1在view.m文件中使用时出错-“initializer元素不是编译时常量” 这是我现在拥有的代码-我的GlobalData.h文件: #import <Foundati

我在这里回顾(并尝试)了一些关于单例和NSMutableArray的线程。我不熟悉Objective-C,所以请容忍我

我只想创建几个可以从任何view/.m文件访问的数组

对于单身汉来说,什么是最好(或最简洁)的编码

下面是我现在拥有的和我得到的 在.m'@implementation'处出现1条警告-“未完成执行” 1在view.m文件中使用时出错-“initializer元素不是编译时常量”

这是我现在拥有的代码-我的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
在view.m文件中(简化):

有人能指出问题所在吗?如果有更好的编码,请告诉我-谢谢

编辑

以下是我尝试使用的几个链接:

这里是一个“现代”版本的单一方法,它可以将任何类转换为单一类(在本例中格式为代码片段)。它在iOS4.x或更高版本中工作:

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

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

    return _sharedClient;
}

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

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

YourAppDelegate.h

@property (nonatomic,retain) NSMutableArray *myArray;
YourAppDelegate.m

@synthesize myArray;
YourViewController.m

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

从这一点开始,您可以对该值进行任何操作。

这是我创建单例的方式:

#import "Singleton.h"

Singleton *singleton = [Singleton sharedSingleton];
singleton.firstMutableArray = ...
singleton.secondMutableArray = ...
辛格尔顿

#import <Foundation/Foundation.h>

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

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

+ (id)sharedSingleton;

@end
然后,当你想给你的单身汉打电话时:

#import "Singleton.h"

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

错误
初始值设定项元素不是编译时常量
与创建单例的方式无关。错误在于您如何访问您的singleton。您在函数之外执行此操作:

GlobalData *globDat=[GlobalData getInstance];
这意味着您正试图将全局变量(
globDat
)初始化为表达式
[GlobalData getInstance]
的值。只能将全局变量初始化为“编译时常量”表达式。这意味着像
0
“fred”
8/2
之类的东西。
[GlobalData getInstance]
的值不能在编译时计算,因此不能用于初始化全局变量

相反,只要在当前尝试使用
globDat
变量的函数体内使用
[GlobalData getInstance]


至于警告,
未完成实现
,我看不出缺少什么。可能您没有发布
GlobalData.h
中的所有代码。无论如何,您应该能够单击警告(它出现在编辑器窗口的右侧),并让Xcode显示缺少的内容。

我已经尝试了几次,但都没有成功。这里是本例中的链接,如果它不起作用-这是由于编码错误造成的。它确实有效。我扩展了上面的示例。好的-谢谢-这有效。不过,我对两件事感到困惑:1)上面罗布·马约夫的回答同样有效——我如何给你们两人评分?2) 哪里是加载数据的合适位置-AppDelegate.m或ViewController.m?谢谢。你可以对两个答案都投赞成票,但必须从“正确”答案中选出一个。我会在ViewController中加载数据,除非它是应用程序范围的数据-在应用程序委托中可能更有意义。但您使用的是Singleton.h,它是用户创建的类,对吗?是的,它是。如果只有很少的NSMutableArray,则可能不需要类来管理它们。但我认为单例类是更干净的代码:您可以随时添加任意多的对象,并且在任何项目中都可以重用。我必须弄清楚这一点……单例类似乎需要更多的初始代码,但实现起来要容易得多。@Beppe如果我必须仅在3或4个
ViewControllers
中访问相同的
NSMutableArray
,你推荐这种解决方案吗?我只是想知道什么会更好,将它存储在
AppDelegate
或单例中。@vv88在内存管理方面思考,只要我知道这两种解决方案是相同的。从技术上讲,appDelegate是在启动时创建的,而Singleton是在第一次使用时创建的。这两种方法之间的实际变化是singleton易于重用,如果你有一个大项目,它的可读性。我需要singleton吗?我不确定-我见过各种各样的线程,从来没有达成一致-一些人说这样更好,其他人不同意。。。我尝试过与你建议的类似的调用代码,但没有成功。看这个帖子:我并不是说需要一个单例并选择创建一个单例,而不仅仅是使用已经存在的AppDelegate。。。不过,也可以将可变数组的访问器作为类上的类级方法。在您发布的链接中,其中一个答案建议使用单例来管理全局变量,如复数。。。如果你只有一个数组在周围浮动,那么把它放在应用程序委托中是没有坏处的,所有的东西都可以很容易地找到它。@Kendallhlhelmstettergelner我几乎处于同样的情况。我需要创建一个
NSMutableArray
(用于字典和字符串),可以在3-4个不同的视图控制器中使用。我开始创造一个单身,但我不确定这是不是最聪明的想法。我读了很多关于在
AppDelegate
中存储数据的观点,但在你的评论之后,我有点困惑。你怎么看,一个阵法不会伤害任何东西?我还必须能够根据下载的数据动态更改其内容。到目前为止,
AppDelegate
版本对我来说似乎更容易。您可能需要单例的原因是,您还可以拥有与可变数组相关的管理和元数据功能。但是如果您真正需要的只是可变数组,那么代码越少越好
#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
#import "Singleton.h"

Singleton *singleton = [Singleton sharedSingleton];
singleton.firstMutableArray = ...
singleton.secondMutableArray = ...
GlobalData *globDat=[GlobalData getInstance];