2014-02-11 4 views
0

사용자 입력에 따라 다양하게 정렬 된 데이터를 리턴하는 술어를 작성할 기준 목록이 필요합니다. 따라서 연관된 하위 클래스 파일 SearchSpecs.hSearchSpecs.m과 함께 "SearchSpecs"라는 엔티티를 만드는 것이 합리적 인 것처럼 보였습니다. 이 방법으로 다른 클래스는이 클래스의 메서드와 속성을 사용하여 코어 데이터 가져 오기를 시작하는 "사양 시트"를 만들 수 있습니다.싱글 톤을 만들고 있습니까?

그러나 "싱글 톤"과 관련하여 논쟁이 많이있는 것으로 나타났습니다. 나는 꽤 새로운데, 내 지식으로는 싱글 톤을 만들지 못했고 지금 그렇게하고 있는지 알고 싶습니까?

나는 그것이 전부인 것을 정말로 알지 못하기 때문에 싱글 톤 토론의 불꽃을 다시 열기를 원하지 않는다는 것을 이해하십시오. 그러나 나는 또한 내 앱에 괴물을 만들고 싶지 않다.

내 접근 방식이 안전하고 합리적임을 확신 할 수 있습니까?

은 여기 내 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 

속성이 사용자를 대신해서 처리 할 수 ​​있기 때문에 설정 된 접근자가 중복됩니다. 귀하의 생성, 추가 등은 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

실제로 원본 파일은 여기에 표시된 것처럼 보입니다.이 파일은 "Editor> Create NSManagedObject subclass ..."에 의해 만들어진 방법입니다.이 메서드는 [이 SO 답변]의 제안을 따르기 위해 추가되었습니다 (http://stackoverflow.com/questions/11048086/fill-a-coredata-entity-from-different-viewcontroller). 내가 그것을 쓰는 동안 그것은 약간 여분 것처럼 보였다. OTOH, 많은 목표 C 코드가 처음에는 내 학생 마음에 중복되거나 보답으로 보입니다. 당신이 제공 한 명확성에 대해 많은 감사드립니다! – rattletrap99

0

당신이 가지고있는 것은 단지 대상 일뿐입니다.

는 예를 들어, AppDelegate에싱글에 가장 가까운 것입니다 (하지만 것을 명확히하기위한, 정말 감사 마커스하지 않습니다).

싱글 톤은 응용 프로그램의 수명을 유지하는 정적 개체입니다. 이 정적 객체는 앱의 모든 곳에서 액세스 할 수 있습니다. 이제는 코드를 제공 한 객체를 어디에 보관할 것인가에 달려 있습니다. 앱의 어느 곳에서나 액세스 할 수 있기를 원하고 하나의 참조 만 필요하면 싱글 톤으로 간주됩니다.

도움이 되었기를 바랍니다. 이

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

을 할 수 있기 때문에 당신이 예를 따라서이 아니 싱글을 만들 코딩 :

+1

'AppDelegate'는 (는) 싱글 톤이 아닙니다. 'AppDelegate'는 여러분의 어플리케이션을 제어하는'UIApplication' 인스턴스의 델리게이트 일뿐입니다. 'UIApplication' 또한 싱글 톤이 아니며, 여러분의 어플리케이션은 단지 하나만 가지고있을뿐입니다. 실제로 Apple 프레임 워크에는 실제 싱글 톤이 거의 없습니다. 싱글 톤이라고 믿게하는 많은 편리한 방법. –

+0

그건 의미가 있지만, 프로필의 종류에 맞기 때문에 항상 싱글 톤이라는 인상 아래있었습니다. 감사합니다 @ MarcusS.Zarra –

+0

그것은 단지 대의원입니다. 하나의 델리게이트 만 가질 수는 있지만 그 델리게이트를 다른 것으로 변경할 수없고 현재 델리게이트를 파괴 할 수 없다는 것을 의미하지는 않습니다. 싱글 톤은 독특하고 파괴 할 수없는 객체입니다. AppDelegate는 자격이 없습니다. Apple의 프레임 워크에서 몇 가지 자격이 있습니다. –

-1

해피. 귀하의 구현에 아무런 문제가 없습니다.

그러나 당신은 싱글을 만들고, 당신이

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

    return singleton; 
} 

또는 무언가를 수정할 수 있습니다 (당신이 SearchSpecs 클래스의 속성을보고하지 않음) 정적 메소드와 정적 클래스를 가지고 있지하려는 경우 SearchSpecs 복사본이 하나 밖에없는 것과 비슷합니다. 아마도 싱글 톤을 만드는 더 좋은 방법이있을 것입니다. 이것은 빠르고 빠릅니다.

+1

대신 iOS 7 이후로 사용하십시오. –

+0

@viperking'instancetype'은 iOS 7보다 오래 전에 소개되었으며 실제로 OS와 관련이 없습니다. 문맥상의 컴파일러 키워드입니다. – vikingosegundo

+0

@vikingosegundo 그것은 조용히하지만 우리가 100 % 정확하고 싶다면 자동으로 XCode 5와 새로운 clang으로 소개되었습니다. :) 사실 XCode 5 및 iOS 7로 시작하는 개발자가 사용할 수 있습니다. –

1

싱글 톤은 인스턴스가 하나 뿐인 클래스입니다. 일반적으로 싱글 톤은 단일 인스턴스를 검색하는 sharedInstance 또는 defaultManager과 같은 클래스 메서드가 있기 때문에 인식 할 수 있습니다. 다른 엔티티 유형 만 있습니다.그 중 하나만 만들면 사실상 싱글 톤이 될 수 있지만 더 많은 인스턴스를 만들 수 없다면 기술적으로 싱글 톤이 아닙니다.

귀하의 접근 방식은 적절합니다. 그러나 SearchSpecs 엔티티의 속성을 감안할 때 사전 목록으로 속성 목록에 저장하는 것이 더 편리 할 수 ​​있습니다. 사용 방법에 따라 다릅니다. SearchSpecs의 모든 인스턴스를 검색하여 benchmarkCategory 또는 activityOfInterest의 특정 값을 찾는 것과 같은 작업을 수행하는 경우이를 코어 데이터에 넣고 조건자를 사용하여 올바른 인스턴스를 찾으면 도움이됩니다. 반면에 매번 모든 인스턴스를 실행하는 작업을 수행하는 경우 Core Data를 사용하면 도움이되지 않습니다.

한 쪽 메모 : 스타일의 문제로 SearchSpecs 대신 엔티티의 이름을 SearchSpec으로 지정하는 것이 좋습니다. 각 인스턴스는 단일 검색 사양이므로 나라면 엔티티 이름을 복수화하지 않을 것입니다.

+0

시간을내어 읽고 답해 주셔서 감사합니다! 이 문제를 확대 한 Marcus의 답변을 참조하십시오. – rattletrap99

+0

@ Tom - 엔티티 이름의 복수화에 대한 올바른 포인트를 만들었습니다. 개념을 이해합니다.나는 기계 공학적 배경에서 왔지만, 명세표는 일반적으로 하나의 종이라고 할지라도 일반적으로 "spec sheet"또는 단순히 "specs"라고 불릴 것이다. 그리고이 경우 "스펙"은 엔티티의 각 인스턴스의 속성입니다. 따라서, 그 이름을 사용하는 것은 제 두번째 성격이었습니다. 다른 모든 엔티티는 단수로 이름이 지정됩니다. 그러나 나는 우호적 인 알림을 주셔서 감사합니다! – 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은 있지만 instancetype이 없습니다. –

+1

이것은 NSManagedObject의 서브 클래스이므로, 그는 분명히 싱글 톤으로 생성하지 않아야합니다. –

+0

시간을내어 읽고 답변 해 주셔서 감사합니다! 이 문제를 확대 한 Marcus의 답변을 참조하십시오. – rattletrap99

관련 문제