2014-02-11 21 views
0

我需要一個標準列表來創建謂詞來返回根據用戶輸入不同地排序的數據。因此,創建一個名爲「SearchSpecs」的實體與其關聯的子類文件SearchSpecs.hSearchSpecs.m似乎是合理的。通過這種方式,我的其他類可以使用此類中的方法和屬性實質上創建一個「規格表」,從中啓動核心數據提取。我正在創建一個Singleton嗎?

但是,我注意到,關於「單身人士」似乎有相當多的爭議。我很新,據我所知,從來沒有創建過一個單身人士,並且想知道我現在是否在這樣做?

明白我不想重新打開或粉碎單身人士辯論的火焰,因爲我並不真正瞭解它的全部內容。但我也不想在我的應用程序中創建一些怪物。

有人可以向我保證我的方法是安全合理的嗎?

下面是相關的代碼從我SearchSpecs.hSearchSpecs.m文件:

// 
// SearchSpecs.h 
// WMDGx 
// 
// Created by Tim Jones on 2/7/14. 
// Copyright (c) 2014 TDJ. All rights reserved. 
// 

#import <Foundation/Foundation.h> 
#import <CoreData/CoreData.h> 


@interface SearchSpecs : NSManagedObject 


// Properties 

@property (nonatomic, retain) NSDate * fromDate; 
@property (nonatomic, retain) NSDate * toDate; 
@property (nonatomic, retain) NSString * categoryOfInterest; 
@property (nonatomic, retain) NSString * activityOfInterest; 
@property (nonatomic, retain) NSString * benchmarkCategory; 
@property (nonatomic, retain) NSString * benchmarkActivity; 

// Set Methods 

- (void) setActivityOfInterest:(NSString *)activityOfInterest; 
- (void) setCategoryOfInterest:(NSString *)categoryOfInterest; 
- (void) setBenchmarkActivity:(NSString *)benchmarkActivity; 
- (void) setBenchmarkCategory:(NSString *)benchmarkCategory; 
- (void) setFromDate:(NSDate *)fromDate; 
- (void) setToDate:(NSDate *)toDate; 

// Create and delete 

- (void) createFreshSpecSheet; 
- (void) saveSpecSheet; 
- (void) deleteSpecSheet; 

@end 

// 
// SearchSpecs.m 
// WMDGx 
// 
// Created by Tim Jones on 2/7/14. 
// Copyright (c) 2014 TDJ. All rights reserved. 
// 

#import "SearchSpecs.h" 


@implementation SearchSpecs 

@dynamic toDate; 
@dynamic fromDate; 
@dynamic benchmarkCategory; 
@dynamic benchmarkActivity; 
@dynamic categoryOfInterest; 
@dynamic activityOfInterest; 


- (void) setActivityOfInterest:(NSString *)activityOfInterest 
{ 

} 

- (void) setCategoryOfInterest:(NSString *)categoryOfInterest 
{ 

} 

- (void) setBenchmarkActivity:(NSString *)benchmarkActivity 
{ 

} 

- (void) setBenchmarkCategory:(NSString *)benchmarkCategory 
{ 

} 

- (void) setFromDate:(NSDate *)fromDate 
{ 

} 

- (void) setToDate:(NSDate *)toDate 
{ 

} 

- (void) createFreshSpecSheet 

{ 

} 

- (void) saveSpecSheet 
{ 

} 

- (void) deleteSpecSheet 
{ 

} 



@end 

感謝您的幫助!

回答

5

現在你知道這不是一個單身人士。它也不是NSManagedObject的正確子類。爲什麼?您正在定義屬性和訪問器。這會給你造成一些困惑。您的標題應顯示爲:

@interface SearchSpec : NSManagedObject 

// Properties 

@property (nonatomic, retain) NSDate *fromDate; 
@property (nonatomic, retain) NSDate *toDate; 
@property (nonatomic, retain) NSString *categoryOfInterest; 
@property (nonatomic, retain) NSString *activityOfInterest; 
@property (nonatomic, retain) NSString *benchmarkCategory; 
@property (nonatomic, retain) NSString *benchmarkActivity; 

@end 

set訪問器是多餘的,因爲屬性會爲您執行此操作。您的創建,添加等也是多餘的,因爲這是Core Data將爲您處理的內容。所以你的實現現在看起來像這樣:

@implementation SearchSpec 

@dynamic fromDate; 
@dynamic toDate; 
@dynamic categoryOfInterest; 
@dynamic activityOfInterest; 
@dynamic benchmarkCategory; 
@dynamic benchmarkActivity; 

@end 

很多更清潔。那麼你如何創建一個實例呢?不適用於[[SearchSpec alloc] init]!你要問核心數據爲您創建它:

NSManagedObjectContext *moc = ...; //Use your existing MOC 
SearchSpec *spec = [NSEntityDescription insertNewObjectForEntityForName:@"SearchSpec" inManagedObjectContext:moc]; 

要刪除現有規格:

NSManagedObjectContext *moc = ...; //Use your existing MOC 
SearchSpec *spec = ...; //Your existing spec object 
[moc deleteObject:spec]; 

最後,保存您的規範所做的任何更改:

NSManagedObjectContext *moc = ...; //Use your existing MOC 
SearchSpec *spec = ...; //Your existing spec object 
NSError *error = nil; 
if ([moc save:&error] == NO) { 
    NSLog(@"Error saving spec: %@\n%@", [error localizedDescription], [error userInfo]); 
} 

核心數據爲您管理數據的生命週期。所以你使用上下文來添加/刪除/更新數據對象。

+0

其實,我原來的文件看起來就像你在這裏顯示的那樣 - 這是他們通過「編輯器>創建NSManagedObject子類...」創建的方式。添加這些方法的目的是嘗試遵循[這個SO回答]中的建議( http://stackoverflow.com/questions/11048086/fill-a-coredata-entity-from-different-viewcontrollers)。我寫這些時看起來有點多餘。 OTOH,很多Objective C代碼似乎對我的學生來說是多餘的或者往復的。非常感謝您提供的清晰度! – rattletrap99

0

你有什麼只是一個對象。

例如,您的AppDelegate是最接近於(但它真的不是,感謝馬庫斯的澄清)。

單例是一個靜態的對象,你保持你的應用程序的生命。這個靜態對象可以從應用程序的任何地方訪問。所以現在取決於你想保留你提供代碼的對象的位置。如果您希望能夠從您的應用程序的任何位置訪問它,並且只需要一個引用即可,它被認爲是單身人士。

我希望有幫助! 快樂編碼:)

+1

'AppDelegate'不是一個單身人士。 'AppDelegate'只是恰好是控制應用程序的'UIApplication'實例的委託對象。 'UIApplication'也不是單身,你的應用程序恰好只有一個。在Apple框架中實際上很少有真正的單身人士。只是有很多方便的方法可以讓你相信他們是單身人士。 –

+0

這是有道理的,但我總是在它作爲一個單身人士的印象,因爲它適合配置文件。謝謝@ MarcusS.Zarra –

+0

它只是一個代表。您只能有一個委託,但這並不意味着您不能將委託更改爲其他內容並銷燬當前委託。單身是一個獨特的,堅不可摧的對象。 AppDelegate沒有資格。蘋果框架中幾乎沒有什麼資格。 –

-1

既然你能做到這一點

SearchSpecs *spec = [[SearchSpecs alloc] init]; 

您創建一個實例,因此它不是一個單例。我看到您的實施沒有問題。

但是,如果你想創建一個單身,並沒有與靜態方法(你不看在SearchSpecs類的屬性)的靜態類,你可以修改

-(id)init 
{ 
    static SearchSpecs *singleton; 
    if(singleton == nil) 
     singleton = [super init]; 

    return singleton; 
} 

什麼類似於確保SearchSpecs只有一個副本。不過,可能有更好的方法來創建一個單身人士。這是快速和骯髒。

+1

而不是id自IOS 7以來使用實例類型:) –

+0

@viperking'instancetype'早在iOS 7之前引入,實際上與OS沒有任何關係。它是一個上下文編譯器關鍵字。 – vikingosegundo

+0

@vikingosegundo它只是默默地引入了XCode 5和新的鏗鏘聲,如果我們想100%正確的話:)所以實際上它對於開始於XCode 5和iOS 7的開發者是可用的 –

1

A singleton是隻有一個實例的類。通常你可以識別單身人士,因爲他們有一個名爲類似於sharedInstancedefaultManager的類方法來檢索單個實例。你只是有另一個實體類型。如果你只創建其中的一個,它可能是一個事實上的單例,但它不是技術上的單例,除非不可能創建更多的實例。

您所描述的方法是合理的。儘管你的SearchSpecs實體具有屬性,但是你可能會發現將它們作爲字典數組保存在屬性列表中會更方便。這取決於你將如何使用它們。如果您要做的事情是查找所有具有benchmarkCategoryactivityOfInterest的特定值的SearchSpecs的實例,那麼將它們放入核心數據並使用謂詞查找正確的實例將有所幫助。另一方面,如果你每次都要在所有實例中運行,那麼使用Core Data將無濟於事。

一個方面的說明:作爲風格的問題,我建議命名實體SearchSpec而不是SearchSpecs。每個實例都是單個搜索規範,因此如果是我,我不會將實體名稱複數化。

+0

感謝您花時間閱讀和回答!請參閱Marcus的回答,其中擴大了這個問題。 – rattletrap99

+0

@湯姆 - 你對實體名稱的複數化提出了一個有效的觀點,並且我理解了這個概念。不過,我來自機械工程背景,並且一份規格清單通常稱爲「規格表」,或者簡稱爲「規格」,即使它是單張紙。在這種情況下,「規格」是實體每個實例的屬性。因此,這只是我使用這個名字的第二天性。我所有的其他實體都以單數命名。但我很欣賞友好的提醒! – rattletrap99

+0

我也來自工程背景,所以我很熟悉這個用法。根據您的描述,聽起來像'SearchSpecs'的每個實例大致對應於規格表上的單行,而不是完整的規格。所有實例一起將統稱爲「規格」。但我可能沒有全面瞭解如何使用這個實體。 –

0

你已經宣佈了一個類。這不是一個單身人士。

如果您要強制執行一個以上的SearchSpecs並且所有客戶端共享一個實例,那麼您將擁有一個單例。

您的客戶可以創建多個SearchSpecs實例;每個實例都有自己的數據。

+0

感謝您花時間閱讀和回答!請參閱Marcus的回答,其中擴大了這個問題。 – rattletrap99

0

正如其他人已明確聲明你是不是創建一個單身人士。

問題是你是否想要?如果你打算只有這個類的一個實例,並且由於某種原因能夠引用它形成多個類,那麼你可能想要創建這個類的單例實例。

您可以在您的m添加以下類方法

在您的.h

+ (instancetype) sharedSearchSpecs; 

這樣做

+ (instancetype) sharedSearchSpecs{ 
    static id sharedSearchSpecs = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     sharedSearchSpecs = [[SearchSpecs alloc] init]; 
    }); 

    return sharedSearchSpecs; 
} 

這會給

這個類的一個實例

至於關於單身人士是好還是壞的爭論。這不是一個問題,雖然有些人會認爲它是。這是您需要什麼以及您的項目是否合適和有效的問題。所以去堅果和享受

+0

有沒有instanceType但實例類型:) –

+1

因爲這是NSManagedObject的一個子類,所以他肯定不應該將它創建爲單例。 –

+0

感謝您花時間閱讀和回答!請參閱Marcus的回答,其中擴大了這個問題。 – rattletrap99

相關問題