2009-08-21 4 views
0

웹 기반 데이터를 유지하기로 선택한 방식이 내 iPhone 앱에서 올바른 방법인지 결정하려고합니다.iphone data persistence sanity check

아직 코어 데이터의 복잡함에 익숙하지 않아서 Sqlite를 FMDB 래퍼와 함께 사용하고 있습니다.

나는 theElements 샘플 유사한 싱글을 사용하는 클래스가 : 여기

내가 지금하고 있어요 방법이다. 정적 공유 인스턴스가 만들어지고 두 개 이상의보기간에 공유됩니다. 데이터가 다운로드되어이 클래스의 배열에로드됩니다. 나는 Sqlite에 다운로드를 저장한다. 초기화시 저장된 Sqlite 데이터를로드하고 타임 스탬프마다 웹에서 업데이트를 가져옵니다.

"올바른"방법입니까? 이게 제대로 보이나요?

간결하게하기 위해 의사 코드를 많이 잘라 냈습니다.

@implementation theClass 
static theClass *sharedInstance = nil; 
... 
- (void)requestDone:(Request *)request 
{ 
    NSDictionary *results=[[request responseString] JSONValue]; 
    [self._array removeAllObjects]; 
    [self._array addObjectsFromArray:results]; 
    [self updateDatabase]; //stores any new results 
    [[NSUserDefaults standardUserDefaults] setObject:self.lastUpdated forKey:@"LastAccessed"]; 
    [[NSUserDefaults standardUserDefaults] synchronize]; 
    [self didFinish]; 
} 
-(void)setupArray { 
    self._array=[NSMutableArray array]; 
    ... 
} 
... 
-(void)getUpdates { 
    NSURL *jsonURL = [NSURL URLWithString:@"URL TO THE WEBDATA"]; 
    request = NSURLRequst.... 
} 
- init { 
    if (self = [super init]) { 
     [self setupArray]; 
    } 
    return self; 
} 

+ (theClass *)shared { 
    @synchronized(self) { 
     if (sharedInstance == nil) { 
      [[self alloc] init]; // assignment not done here 
     } 
    } 
    return sharedInstance; 
} 

+ (id)allocWithZone:(NSZone *)zone { 
    @synchronized(self) { 
     if (sharedInstance == nil) { 
      sharedInstance = [super allocWithZone:zone]; 
      return sharedInstance; // assignment and return on first allocation 
     } 
    } 
    return nil; //on subsequent allocation attempts return nil 
} 

- (id)copyWithZone:(NSZone *)zone { 
    return self; 
} 

- (id)retain { 
    return self; 
} 

- (unsigned)retainCount { 
    return UINT_MAX;} 

- (void)release { 
    //do nothing 
} 

- (id)autorelease { 
    return self; 
} 
+0

http : //cocoawithlove.googlepages.com/SynthesizeSingleton.h.zip 매크로를 사용하면 클래스를 직접 코딩하는 대신 싱글 톤으로 만들 수 있습니다. 그냥 + (ClassName *) sharedClassName을 추가하십시오; (ClassName 대체) 구현에서 synthesizesingleton.h 파일을 가져오고 SYNTHESIZE_SINGLETON_FOR_CLASS (ClassName);을 수행하십시오. 이점은 여러 개의 싱글 톤 클래스가있는 경우 코드가 중복되지 않는다는 것입니다. – mk12

+0

멋진 팁. 감사! 위의 내용이 데이터 및 영구 저장 장치에 적합한 방법이라고 생각하십니까? –

답변

0

저도 같은 문제에서 찾고 내가 NSUserDefaults가 설정 및 가능한 상태가 아닌 상태 데이터 같은 작은 데이터 세트, 즉,위한 것이라는 결론을 내렸다. 큰 데이터 값 또는 데이터는 [NSArray writeToFile]을 사용하여 파일에 저장하고 [NSArray initFromFile]을 사용하여 다시 읽는 것으로 나타납니다.

응용 프로그램에 할당 된 경로를 쿼리하고 파일 이름을 추가해야합니다. 내가 아직 배운 것은 파일 존재 여부, 삭제 방법 (또는 다른 방법으로 삭제/재설정)을 확인하는 방법입니다.

나는 오늘 밤 실험 할 것이다. 내가하고 싶은 또 다른 일은 XML 파일을 유지하는 것입니다. 그러나 나는 이것이 XML 문자열이라고 생각합니다. 그렇게하면 네트워크에서 데이터를 검색하고 유사한 데이터의 로컬 복사본을로드하는 데 동일한 논리를 공유 할 수 있습니다.

BTW - 싱글 톤의 목적은 무엇입니까? 이미 모든 스레드를 소유하고 있으며 다른 프로세스 (응용 프로그램)가 샌드 박스에 액세스 할 수 없기 때문에 세마포어 (mutex)를 사용할 수 있어야합니다. 내 질문은 도전이 아니야, 그것은 내가 패턴이 iPhone에서 유용하다는 것을 이해하는 데 도움이됩니다.

0

사실 NSUserDefaults plist를 사용하면 마지막으로 업데이트 된 시간 만 스냅 할 수 있습니다 (필요한 경우). 모든 것을 sqlite DB ([self updateDatabase])에 저장합니다.

파일의 존재 여부를 확인하려면 다음

NSString *fullPath = [[[NSBundle mainBundle]bundlePath] stringByAppendingPathComponent:@"filenamehere"]; 
//--or-- 
NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:filenamehere]; 

if ([[NSFileManager defaultManager] fileExistsAtPath:fullPath]) ... 

삭제하려면

[fileManager removeItemAtPath:pathtofile error:NULL]; 

나는 귀하의 질문에 내가 가진 하나의 (다소) 것 같다. 만약 데이터가 애플 리케이션의 여러 viewcontrollers에 액세스 할 때 싱글 톤 클래스가 지속적 데이터 스토리지에 대한 액세스를 처리해야하는지 궁금 해서요. 방금 디자인을 고수했습니다. 아주 큰 앱에서 추측 할 수있는 메모리 문제를 볼 수 있지만 내 앱에서는 잘 작동하기 때문입니다. 그래서 나는 내 자신의 질문에 대답했다고 생각한다.