1

3 つの異なる NSFetchedResultsController を使用して、sqlite データベースからデータ レコードを取得しています。そのうちの 1 つは、デバイス (iOS 3.1.3) でテストしたときに苦労しました。シミュレーター (iOS 4.2、deploymentTarget 3.1.3) で実行すると問題なく動作します。

デバイスでは、フェッチは要求どおりに NSDictionaries でも​​障害でもないオブジェクトを返します。

fetchedResultsController の定義は次のとおりです。

- (NSFetchedResultsController *)fetchedResultsControllerForLocID
{
    if (_fetchedResultsControllerForLocID != nil) 
        return _fetchedResultsControllerForLocID;

    NSSortDescriptor *sortDescriptor_00 = [[NSSortDescriptor alloc] initWithKey: kLocationsDatabaseLocationIDKeyPath 
                                                                      ascending: TRUE];

    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: sortDescriptor_00, nil];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    NSEntityDescription *entity = [NSEntityDescription entityForName: kLocationsDatabaseAlternateNameEntityName
                                              inManagedObjectContext: self.managedObjectContext];
    [fetchRequest setEntity:entity];
    [fetchRequest setFetchBatchSize: 80];

    [fetchRequest setResultType: NSDictionaryResultType];
    [fetchRequest setPropertiesToFetch: [NSArray arrayWithObject: kLocationsDatabaseLocationIDKeyPath]];
    [fetchRequest setReturnsDistinctResults: TRUE];
    [fetchRequest setReturnsObjectsAsFaults: FALSE];
    [fetchRequest setSortDescriptors: sortDescriptors];

    NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest: fetchRequest 
                                managedObjectContext: self.managedObjectContext
                                  sectionNameKeyPath: nil
                                           cacheName: kLocationDatabaseAltNameLocIDRequestCacheName];

    self.fetchedResultsControllerForLocID = theFetchedResultsController;

    [fetchRequest release];
    [theFetchedResultsController release];

    [sortDescriptor_00 release];
    [sortDescriptors release];
    return _fetchedResultsControllerForLocID;
}

実際のフェッチは次のとおりです。

- (void) searchLocationsDBWithFRCFor: (NSString *) locationName
{
    [NSFetchedResultsController deleteCacheWithName: kLocationDatabaseAltNameLocIDRequestCacheName];
    NSString *normLocationName = [self normalizeString: locationName];
    NSPredicate *searchPredicate = [NSPredicate predicateWithFormat:@"(%K >= %@) && (%K <= %@)", kLocationsDatabaseLocationSearchNameKeyPath, normLocationName, kLocationsDatabaseLocationSearchNameKeyPath, [self upperBoundSearchString: normLocationName]];

    [[self.fetchedResultsControllerForLocID fetchRequest] setPredicate: searchPredicate];

    NSError *error = nil;

    if (![self.fetchedResultsControllerForLocID performFetch:&error])
    {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    NSMutableArray *tempArray = [[NSMutableArray alloc] init];

    //this line craches on the device:    
    for(NSDictionary* tempIDDict in [self.fetchedResultsControllerForLocID fetchedObjects])
    {
        [tempArray addObject: [tempIDDict objectForKey: kLocationsDatabaseLocationIDKeyPath]];
    }  

    searchPredicate = [NSPredicate predicateWithFormat:@"(%K IN %@)", kLocationsDatabaseLocationIDKeyPath, tempArray];
    [tempArray release];
    //some more fetching...
}

シミュレーターでは、これらの SQL コールバックを取得します。

2011-01-22 20:31:33.660 App[24386:207] CoreData: sql: pragma cache_size=200
2011-01-22 20:31:33.661 App[24386:207] CoreData: sql: SELECT Z_VERSION, Z_UUID, Z_PLIST FROM Z_METADATA
2011-01-22 20:31:33.664 App[24386:207] CoreData: sql: SELECT DISTINCT t0.ZLOCATIONID FROM ZALTERNATENAME t0 WHERE ( t0.ZLOCATIONSEARCHNAME >= ? AND t0.ZLOCATIONSEARCHNAME <= ?) ORDER BY t0.ZLOCATIONID
2011-01-22 20:31:33.666 App[24386:207] CoreData: annotation: sql connection fetch time: 0.0015s
2011-01-22 20:31:33.666 App[24386:207] CoreData: annotation: total fetch execution time: 0.0024s for 6 rows.

ただし、デバイスで実行すると、次のようになります。

2011-01-22 20:39:07.318 App[241:207] CoreData: sql: pragma cache_size=1000
2011-01-22 20:39:07.324 App[241:207] CoreData: sql: SELECT Z_VERSION, Z_UUID, Z_PLIST FROM Z_METADATA
2011-01-22 20:39:07.348 App[241:207] CoreData: sql: SELECT 0, t0.Z_PK FROM ZALTERNATENAME t0 WHERE ( t0.ZLOCATIONSEARCHNAME >= ? AND t0.ZLOCATIONSEARCHNAME <= ?) ORDER BY t0.ZLOCATIONID
2011-01-22 20:39:07.386 App[241:207] CoreData: annotation: sql connection fetch time: 0.0374s
2011-01-22 20:39:07.388 App[241:207] CoreData: annotation: total fetch execution time: 0.0404s for 16 rows.
2011-01-22 20:39:07.400 App[241:207] CoreData: sql: SELECT DISTINCT t0.ZLOCATIONID FROM ZALTERNATENAME t0 WHERE t0.Z_PK IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ORDER BY t0.ZLOCATIONID LIMIT 80
2011-01-22 20:39:07.407 App[241:207] CoreData: annotation: sql connection fetch time: 0.0061s
2011-01-22 20:39:07.409 App[241:207] CoreData: annotation: total fetch execution time: 0.0085s for 6 rows.

エラーが続かなかったとしても、それほど悪くはありません。

2011-01-22 20:39:07.411 App[241:207] *** -[NSKnownKeysDictionary1 objectID]: unrecognized selector sent to instance 0x1e4f80
2011-01-22 20:39:07.414 App[241:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSKnownKeysDictionary1 objectID]: unrecognized selector sent to instance 0x1e4f80'
2011-01-22 20:39:07.417 App[241:207] Stack: (
861696817,
860329709,
861700631,
861203093,
861166272,
832412333,
832413791,
77245,
66451,
66643,
845720837,
861449139,
861447005,
861059891,
861060063,
834770799,
834765939,
12391,
12316
)
terminate called after throwing an instance of 'NSException'
Program received signal: “SIGABRT”.

デバイスで実行している場合、Core Data がクエリを変更するのはなぜですか?

NSKnownKeysDictionary1 とは正確には何ですか? また、コントローラーの fetchedObjects にアクセスしようとすると、デバイスでエラーが発生するのはなぜですか?

何か案は?前もって感謝します!

4

1 に答える 1

2

次の行を削除して、問題が解決するかどうかを確認します。[fetchRequest setFetchBatchSize:80];

アプリは正常に動作しましたが、SDK4.2でビルドされたiOS3.xデバイスでクラッシュするという同様の問題がありました。私はここで解決策を見つけました: iPhone OS4(XCode 3.2.3)のsetFetchLimitとsectionNameKeyPathはクラッシュを引き起こします

于 2011-01-26T16:18:19.670 に答える