ios 다중 루틴 환경에서 데이터베이스 구조

6425 단어 다중 스레드
IOS 프로그램 설계에서는 일반적으로 현지화된 데이터를 관리해야 한다.응용 프로그램은 우리에게 다양한 방식으로 로컬화된 데이터를 제공합니다. 예를 들어 코어 데이터, 일반적인 평면 파일, 물론 sqlite도 있습니다.core 데이터는 애플의 공식 문서에서 고급 기능이라고 하기 때문에 초보 프로그래머에게 사용하지 말라고 권장하지 않는다.나는 대략 코어 데이터를 연구해 보았는데, 어쨌든 애플의 원생적인 것이다.많은 곳에서 애플의 원생 시스템과 잘 결합되어 있다.예를 들어 코어 데이터를 UItableView의 데이터 원본으로 직접 사용할 수 있어 프로그래밍 효율이나 프로그램의 우아형에서 많이 향상되었다.그러나 애플이 말한 바와 같이 이것은 고급 기능이기 때문에 사용하기가 좀 힘들다. 특히 다선정 환경에서는 그렇다.sqlite를 사용했기 때문에 로컬화할 때 sqlite의 물건을 많이 봤습니다.
애플은 sqlite 라이브러리 파일만 제공합니다. sqlite를 사용하려면 sqlite를 다시 봉해야 합니다.처음에, 나는 C++로 간단한 데이터베이스를 봉하여 상부에서 호출하기 편리하게 했다.하지만 사용 과정에서 다선정으로 갈수록 문제가 생겼다.qlite는 다중 루틴 환경에서 세 가지 실행 모드가 있습니다: 참조 (http://blog.csdn.net/diyagoanyhacker/article/details/7209888)
단일 루틴: 모든mutex 자물쇠를 비활성화하고 사용할 때 오류가 발생합니다.SQLite 컴파일할 때 SQLITE 추가THREADSAFE=0 매개 변수 또는 SQLite를 초기화하기 전에 sqlite3 호출config(SQLITE CONFIG SINGLETHREAD)일 때 활성화됩니다. 
다중 루틴: 데이터베이스 연결이 여러 루틴에 동시에 사용되지 않으면 안전합니다.소스에는 bCoreMutex가 활성화되어 있고 bFullMutex가 비활성화되어 있습니다.실제적으로 데이터베이스 연결과preparedstatement(준비된 문장)에 있는 자물쇠를 사용하지 않기 때문에 여러 라인에서 같은 데이터베이스 연결이나preparedstatement를 동시에 사용할 수 없습니다.SQLite 컴파일할 때 SQLITE 추가THREADSAFE=2 매개변수는 기본적으로 활성화됩니다.SQLITETHREADSAFE는 0이 아닙니다. SQLite를 초기화하기 전에 sqlite3 를 호출할 수 있습니다.config(SQLITE CONFIG MULTITHREAD) 활성화또는 데이터베이스 연결을 만들 때 SQLITE 설정OPEN_NOMUTEX flag. 
직렬: bCoreMutex 및 bFullMutex를 포함한 모든 잠금을 활성화합니다.데이터베이스 연결과preparedstatement가 모두 잠겨 있기 때문에 다중 루틴이 이 대상을 사용할 때 병발할 수 없고 직렬로 변합니다.SQLite 컴파일할 때 SQLITE 추가THREADSAFE=1 매개변수는 기본적으로 활성화됩니다.SQLITETHREADSAFE는 0이 아닙니다. SQLite를 초기화하기 전에 sqlite3 를 호출할 수 있습니다.config(SQLITE CONFIG SERIALIZED) 활성화또는 데이터베이스 연결을 만들 때 SQLITE 설정OPEN_FULLMUTEX flag.、
애플이 제공한 라이브러리는 테스트를 한 결과 컴파일할 때 두 번째 방식을 사용한 것으로 밝혀졌다.두 번째 방식은 여러 라인이 같은 데이터베이스를 읽고 쓰는 문제를 해결하는 것이다.그러나 같은 데이터베이스 연결은 여러 개의 루트 간에 공유할 수 없다.하나의 해결 방안은 모든 라인에 데이터베이스 연결을 생성하는 것이다.그래서 데이터베이스 연결을 빈번하게 열고 닫아야 한다.sqlite를 열고 닫는 데 소모되는 시간은 그리 크지 않지만 매번 열 때마다 시스템은 이 데이터베이스 연결을 위해 메모리를 캐시로 개척하지만 라이브러리 연결을 닫을 때 회수하지 않는다(회수 메커니즘이 명확하지 않다).애플은 휴대전화 프로그램이 차지하는 메모리가 20MB를 넘으면 안 된다고 조언했다. 이렇게 여러 번 켜고 끄면 데이터베이스 캐시 문제로 인해 프로그램의 메모리 사용량이 20MB를 넘어설 수 있다.그래서 절충할 방안이 하나도 없네요.나는 인터넷에서 많은 ios에서 sqlite의 소스 라이브러리를 찾았는데, 결국 많은 프로그램들이 사용하고 있는 FMDB (https://github.com/ccgus/fmdb).이 라이브러리는 다중 루틴을 Blocks로 처리하여 여러 루틴 간에 데이터베이스 연결을 공유할 수 있습니다.이 라이브러리를 사용하면 전체 프로그램이 실행되는 동안 몇 개의 데이터베이스 연결만 유지할 수 있다.
 
전체 프로그램이 다중 루틴 환경에서의 데이터베이스 구조가 명확해지기 시작했다.
데이터베이스 연결 클래스WizDataBase는 FMDB의 데이터베이스 연결을 유지하고 프로그램에 대한 데이터베이스 조회 방법을 제공합니다.이 클래스는 WizDataBaseDeleage 프로토콜을 실현합니다.WizDataBaseDeleage 프로토콜은 프로그램에서 데이터 상호작용이 필요한 모든 데이터베이스 작업을 정의합니다.그리고 나서
/*

WizDataBaseDelegate.h

*/

@protocol WizDataBaseDelegate



//  

@end

/*
WizDataBase.h
*/
@interface WizDataBase<WizDataBaseDelegate>
{
  FMDB* fmdb;
......
}
@end

 
데이터베이스 관리 클래스(단일 예) WizDataBase Manager는 데이터 연결을 유지 관리합니다.WizDataBaseDeleage 프로토콜을 충족하는 객체가 실제로 제공됩니다.특정 WizDataBase 객체가 아니라이렇게 하면 인터페이스와 유사한 방식으로 데이터베이스 층을 구체적으로 차단하고 필요한 구체적인 핑계에만 관심을 가질 수 있다.
  
#import "WizDataBase.h"

#import "WizDataBaseDelegate.h"



@interface WizDbManager()

{

    NSMutableDictionary* dbDataDictionary;

}

@property (atomic, retain) NSMutableDictionary* dbDataDictionary;

- (void) clearDataBase;

- (id<WizDataBaseDelegate>) getWizDataBase;

@end



@implementation WizDbManager

@synthesize dbDataDictionary;

- (void) dealloc

{

    [dbDataDictionary release];

    [super dealloc];

}

...........



@end

 
사용 중인 경우 WizDataBase Manager에 WizDataBase를 요청한 다음 를 사용합니다.여기서 흔히 볼 수 있는 데이터베이스 응용 장면을 살펴보자면 MVC의 모델 컨트롤러를 사용하여 데이터베이스에서 데이터를 읽고 UI를 업데이트하는 것이다.데이터베이스를 읽는 것은 당연히 매우 힘든 작업이다. 만약에 메인 라인이 데이터베이스를 읽는 데 바쁘게 한다면 UI의 응답을 낮추고 인터페이스를 매우 끊겨 보일 것이다.따라서 데이터를 읽는 작업을 다중 루트로 처리할 필요가 있다.애플은 NSOperation, GCD, Thread 등 다양한 멀티스레드 처리 방식을 제공합니다.이런 장면에서 가장 적합한 것은 GCD다.예를 입력합니다.
   
dispatch_async(dispatch_get_global_queue(0, 0), ^{

        if (nil == documentGuid) {

            return;

        }

        id<WizDataBaseDelegate> dataBase = [[WizDataBaseManager shareDbManager] getWizTempDataBase];

        WizAbstract* abstract = [dataBase abstractOfDocument:documentGuid];

        dispatch_async(dispatch_get_main_queue(), ^{

            if (nil == abstract) {

                return;

            }

            [self.data setObject:abstract forKey:documentGuid];

           imageView.image = abstract.image;

        });

    });

좋은 웹페이지 즐겨찾기