역시 여러분의 CoreData 사용법도 안 맞아요.

15686 단어 potatotipsiOS
<이 기사는본사의 블로그도 전재하였다>
조금만 걸으면 땀이 나고 봄의 햇살을 느낄 수 있다.
안녕하세요yimajo.
쿡패드는 매달 한 번제6회 포테이토칩 개발 팁 공유회을 개최하는데, 제가 참가할 수 있도록 허락해 주시고"역시 여러분의 CoreData 사용법은 틀렸습니다."라는 제목으로 발표해 주십시오.
이번이 세 번째 발표&참가이기 때문에 과거 자신이 발표한 것도 연결해야 한다.
  • 포테이토틱스 #5 쿡패드에 잡스도 부처가 될 수 있는 개발 팁을 발표했습니다.
  • 역시 너희 iOS 7 대응은 틀렸어.
  • 이번 개최 장소는 UIEvolution 주식회사로, 언론에 공개되지 않은 사내를 살짝 체험할 수 있다.

    (사진은 해외 교우 시스템 iOS 애플리케이션에 사용되는 라이브러리의 설명을 듣는 곳)
    그나저나 사진 오른쪽은 술집 테이블인데 거기서 발표된 분위기를 전달할 수 있을까.왼쪽은 사무실로 발표할 때 야근 분위기가 살짝 느껴진다.

    본 문제는 CoreData를 사용할 때 무엇을 틀렸습니까


    자신이 발표한 내용은 코어데이터에 관한 다음 3개다.
  • AppDelegate를 통해 NSManagedObject Context 생성
  • CoreData의 데이터가 모두 NSFetcheedResults Controller
  • 가 필요한 것은 아닙니다.
  • NSManagedObject의 하위 클래스를 자동으로 생성하지만 데이터에 대한 접근은 setValue:forKey
  • 를 사용합니다.
    순서대로 설명하다

    AppDelegate를 사용하여 NSManagedObject Context를 생성한 후 저장하지 않음


    Apple의 Xcode 템플릿에서 생성된 CoreData 코드에서는 NSManagedObject Context가 AppDelegate에서 생성되고 저장되지만, iOS로부터 수신 처리를 수행하는 AppDelegate의 역할로 데이터의 지속화를 위해 NSManagedObject Context를 생성하는 것은 오류입니다.
    이것을 템플릿으로 실제 프로젝트에서 사용하면 AppDelegate는 점점 비대해집니다
    ()゜Д゜(;)
    구체적으로 Xcode의 Use Core Data에 확인란을 삽입할 때 생성되는 템플릿은 다음 코드입니다.
    #pragma mark - Core Data stack
    
    // Returns the managed object context for the application.
    // If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
    - (NSManagedObjectContext *)managedObjectContext
    {
        if (_managedObjectContext != nil) {
            return _managedObjectContext;
        }
    
        NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
        if (coordinator != nil) {
            _managedObjectContext = [[NSManagedObjectContext alloc] init];
            [_managedObjectContext setPersistentStoreCoordinator:coordinator];
        }
        return _managedObjectContext;
    }
    
    // Returns the managed object model for the application.
    // If the model doesn't already exist, it is created from the application's model.
    - (NSManagedObjectModel *)managedObjectModel
    {
        if (_managedObjectModel != nil) {
            return _managedObjectModel;
        }
        NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreDataXcodeTemplate" withExtension:@"momd"];
        _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
        return _managedObjectModel;
    }
    
    // Returns the persistent store coordinator for the application.
    // If the coordinator doesn't already exist, it is created and the application's store added to it.
    - (NSPersistentStoreCoordinator *)persistentStoreCoordinator
    {
        if (_persistentStoreCoordinator != nil) {
            return _persistentStoreCoordinator;
        }
    
        NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataXcodeTemplate.sqlite"];
    
        NSError *error = nil;
        _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
        if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
            /*
             Replace this implementation with code to handle the error appropriately.
    
             abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
    
             Typical reasons for an error here include:
             * The persistent store is not accessible;
             * The schema for the persistent store is incompatible with current managed object model.
             Check the error message to determine what the actual problem was.
    
    
             If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.
    
             If you encounter schema incompatibility errors during development, you can reduce their frequency by:
             * Simply deleting the existing store:
             [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]
    
             * Performing automatic lightweight migration by passing the following dictionary as the options parameter:
             @{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES}
    
             Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.
    
             */
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }    
    
        return _persistentStoreCoordinator;
    }
    
    
    AppDelegate가 해야 할 일인가요?그렇습니다.

    CoreData에서 데이터를 가져오는 데 NSFetchedResults Controller가 필요한 것은 아닙니다.


    UItableView를 사용하여 저장된 데이터 1개를 1개cell에 직접 표시하는 사용법은 NSFetcheedResults Controller에 적합합니다. 그룹을 나누면 각section마다 데이터를 분리할 수 있기 때문에 indexPath로 데이터에 직접 접근할 수 있습니다.또한section용 속성은 동적 제작이 가능하여 매우 편리합니다.
    참조: N-SfetchedResulttsController 일자별 영역 요약 방법
    http://qiita.com/takayama/items/aa3a7acd2f40ffb93dfb
    그러나 모든 데이터 취득에는 N SFetchedResults Controller를 사용할 필요가 없습니다. 예를 들어 취득하고자 하는 데이터가 특정한 데이터라면 NSFetched Request로 충분합니다.

    NSManagedObject의 하위 클래스를 자동으로 생성하고 setValue:forKey를 사용하여 데이터에 액세스


    NSManagedObject의 하위 클래스가 자동으로 생성되고 이 하위 클래스 속성을 사용하면 데이터 세트는 점문법으로만 접근할 수 있지만 NSManagedObject#setValue:<#대상#>forKey:<#키이름#>KeyValue 형식으로 데이터에 접근하는 예도 흔하다.
    이것도 X코드가 생성한 템플릿이 정확하다고 생각했기 때문이라고 생각합니다.
    우선 키워드 값으로 학급 방문을 만드는 예
    //Eventというクラスを文字列指定で編集しようとする
    NSEntityDescription *entity
      = [NSEntityDescription entityForName:@"Event" 
                    inManagedObjectContext:managedObjectContext];
    
    
    //NSManagedObjectをそのまま使っているので
    //setValue:forKeyによりキー値コーディングすることになる
    [entity setValue:@(1) forKey:@“num"];
    [entity setValue:@"hoge" forKey:@“name"];
    
    
    그리고 점 구조로 자동으로 생성된 클래스로부터 접근하는 예
    //クラス名を文字列で取得して名前で呼び出せるように準備
    //EXMSubClassは自動生成したNSManagedObjectのサブクラス
    NSString *className = NSStringFromClass([EXMSubClass class]);
    
    EXMSubClass *entity
      = [NSEntityDescription entityForName:className 
                    inManagedObjectContext:managedObjectContext];
    
    
    //サブクラスにnumの属性があればプロパティでアクセスできる
    entity.num = @(1);
    entity.name = @"hoge";
    
    Xcode에서 생성된 템플릿의 코드는 NSManagedObject의 하위 클래스를 자동으로 생성하지 않기 때문에 전자처럼 자동으로 생성된다면 이러한 추상화는 거의 의미가 없고 재전환 시 효율도 떨어질 수 있다.

    총결산


    Xcode의 코드 템플릿 자체는 가장 좋은 실천 방식이 아니며 대다수 상황에 따라 불필요한 방법으로 변하기 때문에 템플릿에서 프로젝트를 만들지 않는 것이 좋다.
    또한 제가 발표한 내용도 제품의 성격과 프로젝트 구성원의 경험에 의존하거나 그간의 화제에 의존하는 경우 등 당연히 결정된 개발 기간 내에 모바일 제품을 먼저 제작하는 것이 절대 우선순위가 높습니다.하지만 더 좋은 방법이 있다면, 아니, 실제로 틀에 따라 제작하는 것이 좋다면 댓글을 써도 되지만, yimajo가 이상한 말을 하는 것을 막기 위해 포테이토피프에 참가하는 계기가 될 수 있다.

    끝말



    (사진은 줄을 서 있을 때 찍은 쿡패드 회사gfx씨의 사진)
    사진으로는 전달할 수 없지만 UIEvolution사도 삽입식 기기를 개발하고 있는 것 같다. 사무실 곳곳에 자동차 내비게이션 등 기기가 있고 소프트웨어 전문 업체가 없는 분위기가 있다.내가 막 졸업하고 들어간 회사는 반도체 제조 공장이어서 그립다.
    다음 포테이토피프 #6은 DeNA 회사가 개최하는 곳이라고 합니다.제가 이런 학습가에 다니면서 눈에 띄는 것은 이런 모임을 여는 회사에서 엔지니어를 채용할 때 업무 내용뿐만 아니라 현재의 과제를 털어놓으면 참가자들도 토로하겠죠.겉으로만 보이는 업무 내용에 관심이 없어도 과제를 해결할 수 없다는 점에서 더 많은 말을 듣고 싶고, 일할 때의 인상도 얻을 수 있지 않을까 싶습니다.
    발표회 후 iOS 애플리케이션 엔지니어라면 누구나 아는'아이폰 프로그래밍 UIKit 상해 참고서'@tokorom라는 서명을 받았다.




    UIKit에 관한 자세한 책으로, 아이폰 앱 개발 현장에서 테이블 위에서 가장 흔한 책이다.참고로 그 부품의 사용법은 어떻게 할지 생각할 때 작용했다.

    좋은 웹페이지 즐겨찾기