2012-01-19 46 views
5

我已經回顧(並嘗試過)關於Singletons和NSMutableArrays的一堆線程。我是Objective-C的新手,請耐心等待。爲Xcode 4創建/使用Singleton NSMutableArray的正確方法

我只是想創建幾個可以從任何視圖/ .m文件訪問的數組。

Singleton的最佳(或最簡潔)編碼是什麼?

下面是我現在和我得到的.m「@implementation」 1警告 - 「完全執行」,在視圖中的.m文件使用 1的錯誤 - 「初始元素不是一個編譯時間常數「

這是我現在的代碼 - 我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 

我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 

而且在一個視圖.m文件(簡體):

#import GlobalData.h 

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

有人可以指出麻煩,如果有更好的編碼,請賜教 - 謝謝!

編輯

下面是我試圖用幾個環節:

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

iPhone help with singleton class

+0

使用馬特Galaghers [單身骨骼](http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html)。 – Till

回答

8

在這種情況下,你可能會做更多的比你要:通過調用應用程序代理,這是得到了 - 你可以使用內置的單。當然,這並不總是最好的解決方案 - 但是你可以把你的NSMutableArray作爲一個屬性放在你的App Delegate中,然後在任何視圖中輕鬆地引用它。通過這樣做 - 你並不是將它作爲一個「單例」來鎖定,但它有一個「單例實例」(這對於可測試性有很大的幫助)。

我已經簡化了這裏這個過程:

YourAppDelegate.h

@property (nonatomic,retain) NSMutableArray *myArray; 

YourAppDelegate.m

@synthesize myArray; 

YourViewController.m

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

從這點 - ÿ你可以對這個值做任何操作。

+0

我已經嘗試了幾次沒有成功。這裏的鏈接http://stackoverflow.com/questions/8918396/how-to-share-a-variable-between-multiple-views-xibs – wayneh

+0

在這種情況下,如果它不工作 - 這是由於編碼錯誤。它確實有效。 – dtuckernet

+0

我在上面的示例中進行了擴展。 – dtuckernet

6

這裏有一個方法的「現代版」將任何類成單例(在這種情況下,格式化爲代碼段)。它適用於iOS4.x或更高版本:

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

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

    return _sharedClient; 
} 

但是,你真的需要一個單一的NSMutableArray嗎?

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

我需要一個Singleton嗎?我不確定 - 我看過各種線程,從來沒有達成一致 - 有人說它更好,其他人不同意...我已經嘗試了類似的調用代碼,以避免你的運氣。看到這個線程:http://stackoverflow.com/questions/8918396/how-to-share-a-variable-between-multiple-views-xibs – wayneh

+0

我不是那麼談論需要一個單身人士,並選擇創建一個而不是僅僅使用已經存在的AppDelegate ...雖然您也可以將可變數組的訪問器作爲類的類級方法。在發佈的鏈接中,您發佈了其中一個答案,建議使用單例管理全局變量S,如複數形式......如果您只有一個數組,則將其放入所有可輕鬆訪問的應用程序委託中。 –

+0

@KendallHelmstetterGelner我幾乎處於相同的情況。我需要創建一個'NSMutableArray'(用於字典和字符串),我可以在3-4個不同的視圖控制器中使用。我開始創建一個單身人士,但我不確定,這是最聰明的想法。我已經閱讀了很多關於在AppDelegate中存儲數據的看法,但是在你的評論之後我有點困惑。你怎麼看,一個陣列不會傷害什麼?我還必須能夠根據下載的數據動態更改其內容。到目前爲止,AppDelegate版本對我來說更加容易。 – rihe

3

這是我創作的方式我辛格爾頓:

Singleton.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

#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 = ... 
+0

但是你使用Singleton.h這是一個用戶創建的類,對嗎? – wayneh

+0

是的。如果你只有幾個NSMutableArray,你可能不需要一個類來管理它們。但我認爲Singleton類是更簡潔的代碼:您可以隨時添加任意數量的對象,並且可以在任何項目中重用。 – Beppe

+0

我必須弄清楚這一點...單身人士似乎需要更多的初始代碼,但實施起來要容易得多。 – wayneh

5

錯誤initializer element is not a compile-time constant與您創建單身人士的方式無關。錯誤是你如何訪問你的單身人士。你正在做一個函數的本次外:

GlobalData *globDat=[GlobalData getInstance]; 

這意味着您正試圖初始化一個全局變量(globDat)作爲表達[GlobalData getInstance]的價值。您只能將全局變量初始化爲「編譯時常量」的表達式。這意味着像0"fred"8/2之類的東西。 [GlobalData getInstance]的值不能在編譯時計算,所以不能用於初始化全局變量。

相反,只要在當前嘗試使用globDat變量的任何位置使用[GlobalData getInstance]即可。

至於警告,Incomplete implementation,我沒有看到有什麼缺失。也許你沒有發佈GlobalData.h的所有代碼。無論如何,你應該能夠點擊警告(它出現在編輯器窗口右側)並讓Xcode顯示你缺少的東西。

+0

謝謝 - 你是對的,我沒有在一個方法。它現在有效。我如何分享信貸的答案,因爲下面的dtuckernet也提供了正確的答案? – wayneh

+0

每個問題只能接受一個答案。但是你可以得到任何數量的答案。 –

+0

對不起 - 爲了破壞你,但現在我已經得到了Singleton的工作,似乎我無法修改我的數組!我沒有收到任何編譯器錯誤或警告。我的'addObject'努力似乎沒有做任何事情。 – wayneh