1

여러 기존 앱에서 사용하기 위해 모델 레이어를 다시 작성하는 중입니다. 기존 코드베이스는 날짜가 있기 때문에 향후 더 쉽게 확장 할 수있는 방법을 일반화하고 최신 언어/기술 추가 (ARC) 방법의 이점을 얻으려고합니다.Objective-C 접근 자 템플릿

내 목표는 단순한 데이터베이스 계층 (FMDatabase 위에 구축 됨)과 강력한 모델 개체 클래스로 구성되어 있으며 대부분의 복잡성을 캡슐화하는 이식 가능한 SQL 기반 "프레임 워크"입니다. 모델 개체는 주 수퍼 클래스에서 하위 클래스로 만들고 계약을 준수하여 SQL 동작을 용이하게하는 데 필요한 속성 및 스키마 세부 정보를 제공하는 메서드를 구현 (및 재정의)합니다.

나는이 접근 방식을 PHP에서 많이 사용했지만 Objective-C로 문제가 발생했습니다.

예, CoreData는 이러한 기능을 제공하지만 여러 가지 이유로 옵션이 아닙니다. 또한 런타임에 문제를 해결하는 솔루션을 보았지만 ARC와 함께 작동하는지 확신 할 수 없으며 컴파일하기 전에 접근자를 생성하는 것을 선호합니다.

나는 멀티 스레드 GCD 기반의 접근 방식 (question raised here) 대 액세스 다음과 같은 패턴으로 만난다위한 잠금 기반 패턴 유지 토론 시작 : 나는 그것을 좋아하지

- (NSDate *)creationDate { 
    __block NSDate *aDate; 
    dispatch_sync(accessorQueue, ^{ 
     aDate = creationDate; 
    }); 
    return aDate; 
} 

- (void)setCreationDate:(NSDate *)aDate { 
    if (![aDate isKindOfClass: [NSDate class]]) { 
     NSLog(@"setCreationDate: called with non-date object); 
     return; 
    } 

    dispatch_barrier_async(accessorQueue, ^{ 
     if ((!creationDate && aDate) || ![aDate isEqualToDate: creationDate]) { 
      [self willChangeValueForKey: @"creationDate"]; 

      [changes setObject: aDate ? aDate : [NSNull null] 
         forKey: @"creationDate"]; 

      creationDate = aDate; 

      [self didChangeValueForKey: @"creationDate"]; 
     } 
    }); 
} 

을하지만 난되고 싶어요 모델 개체 코드를 단순화하기 위해 속성 목록을 생성 할 수 있습니다. 내 첫 번째 단계는 매크로 확장을 생성하여 접근 자/변형자를 작성하는 것입니다. 여기에서는 이미 완벽하지 않은 옵션을 사용했습니다.

1) 매크로 목록을 반복하는 것은 추악한 과정입니다. Boost.preprocessor는 옵션이 될 수 있지만 고려하면 (2 & 3) 나에게 무서워.

2) 사용 된 토큰의 모든 가능한 버전으로 매크로를 전달해야합니다 (예 : 위 예제에 대한 getter 및 setter 생성을 만족시키기 위해 creationDate 및 CreationDate를 전달해야합니다.) show- 스토퍼도 이상적이지 않습니다.

3) 객체 및 기본 유형에 다른 매크로 확장이 필요하므로 속성 목록 (1)을 반복하는 것이 훨씬 어렵습니다. 목록의 각 속성에 대해 확장 매크로를 전달할 수 있지만이 "시간 절약"은 이제 꽤 반대 인 것처럼 보입니다. 튜플의 긴 목록은 매크로에 대한 개별 호출 목록보다 훨씬 읽기 쉽지 않습니다.

나는 이것을 가능하게 만든 뭔가를 간과했거나 다른 누군가가 이미 내가 찾지 못한 해결책을 만들었 으면 좋겠다. 어쩌면 접근자를 포함하는 카테고리를 생성하는 전처리 스크립트 ...? 나는이 옵션을 아직 보지 못했지만, 특히 크로스 플랫폼 타겟팅을 위해 다른 언어로 확장 한 경우에는 괜찮을 것입니다.

감사합니다.

+0

"핵심 데이터를 사용하지 않는 이유"에 대해 알고 싶습니다. 핵심 데이터는 탁월하며, 더 나은 버전을 직접 작성하지 않아도됩니다. – jrturton

+0

1) 스키마를 리버스 엔지니어링해야 크로스 플랫폼을 공유하기가 매우 어렵습니다. 예를 들어, 변경 범위가 제한적이라는 것을 보장하는 모든 표준 레이아웃 기술을 인식하지 못합니다. 2) iCloud와 함께 CoreData를 사용하는 문제가 있습니다 (iCloud가 나를위한 진정한 해결책은 아닙니다) - 크로스 플랫폼 동기화 레이어를 제공해야하며 가장 이해가 잘되는 곳에 삽입 할 수 있어야합니다. 3) 나는 CoreData 버그로 인해 과거에 진단을받는 데 시간이 많이 걸렸습니다. 그것들은 내 혀 끝에 붙어있는 것들입니다. # 1은 나를 위해 큰 것입니다. – greg

+0

크로스 플랫폼은 꽤 좋은 이유입니다. – jrturton

답변

0

필자는 모델 개체 헤더 파일의 속성 선언을보고 각 클래스의 새 범주에 사용자 지정 액세서를 작성하는 Python 스크립트를 작성했습니다. 이를 용이하게하기 위해, 나는 형태의 주석 문자열 내 속성 선언에 주석 :

// SqlFieldName SqlFieldType 

그리고 원시적 인 접근 대 개체에 대한 몇 가지 기본 템플릿을 정의했다.

결과는 구현에 따라 달라 지지만 일반적으로 찾기/바꾸기 중 이름 바꾸기에 대한 감독으로 인해 버그가 하나 이상있는 접근 자에 대해 많은 복사/붙여 넣기/찾기/바꾸기 작업을 저장합니다.

범주를 사용하여 접근자를 저장하면 범주의 객체 메서드를 재정의하는 컴파일 경고가 발생하지만 -Wobjc-protocol-method-implementation을 사용하여 무시할 수 있습니다.

내 생성 된 코드는 내 필요에 매우 구체적이지만 아무도 관심이있는 경우 게시 할 것입니다.