2014-02-11 19 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

相关问题