これはStackOverflowに関する私の最初の質問です。エチケットを破っている場合は、すみません。私はObjective-C/アプリの作成にもかなり慣れていません。
私はCS193Pスタンフォードコース、特にCoreDataの講義/デモをフォローしています。Paul HegartyのPhotomaniaアプリでは、彼はテーブルビューから始めて、UIフローを中断することなく、バックグラウンドでデータを入力します。ローカルエリアのビジネスを一覧表示するアプリケーションを作成しています(JSONデータを返すAPIから)。
Paulの写真/写真家のクラスに従ってカテゴリを作成しました。クラス自体の作成は問題ではなく、クラスが作成される場所です。
A simplified data structure:
- Section
- Sub-section
- business
- business
- business
- business
- business
- business
私のアプリケーションは、いくつかのボタンを備えたUIViewControllerで始まり、それぞれが対応するセクションのテーブルビューを開きます(これらはすべて正常に機能します。質問が意味をなすように十分な情報を提供しようとしています)。この質問に基づいたUIManagedDocumentのURLを作成/開くために、ヘルパーメソッドを呼び出します。これは、アプリケーションが実行されるとすぐに呼び出され、すぐに読み込まれます。
PaulのfetchFlickrDataIntoDocumentに非常によく似たメソッドがあります。
-(void)refreshBusinessesInDocument:(UIManagedDocument *)document
{
dispatch_queue_t refreshBusinessQ = dispatch_queue_create("Refresh Business Listing", NULL);
dispatch_async(refreshBusinessQ, ^{
// Get latest business listing
myFunctions *myFunctions = [[myFunctions alloc] init];
NSArray *businesses = [myFunctions arrayOfBusinesses];
// Run IN document's thread
[document.managedObjectContext performBlock:^{
// Loop through new businesses and insert
for (NSDictionary *businessData in businesses) {
[Business businessWithJSONInfo:businessData inManageObjectContext:document.managedObjectContext];
}
// Explicitly save the document.
[document saveToURL:document.fileURL
forSaveOperation:UIDocumentSaveForOverwriting
completionHandler:^(BOOL success){
if (!success) {
NSLog(@"Document save failed");
}
}];
NSLog(@"Inserted Businesses");
}];
});
dispatch_release(refreshBusinessQ);
}
[myFunctions arrayOfBusinesses]は、JSONデータを解析し、個々のビジネスを含むNSArrayを返します。
ビジネス作成コードの開始時と終了時にNSLogを使用してコードを実行しました。各ビジネスにはセクションが割り当てられており、作成には0.006秒かかりますが、これらは数百あります。インサートは約2秒かかります。
ヘルパーメソッドはここにあります:
// The following typedef has been defined in the .h file
// typedef void (^completion_block_t)(UIManagedDocument *document);
@implementation ManagedDocumentHelper
+(void)openDocument:(NSString *)documentName UsingBlock:(completion_block_t)completionBlock
{
// Get URL for document -> "<Documents directory>/<documentName>"
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:documentName];
// Attempt retrieval of existing document
UIManagedDocument *doc = [managedDocumentDictionary objectForKey:documentName];
// If no UIManagedDocument, create
if (!doc)
{
// Create with document at URL
doc = [[UIManagedDocument alloc] initWithFileURL:url];
// Save in managedDocumentDictionary
[managedDocumentDictionary setObject:doc forKey:documentName];
}
// If the document exists on disk
if ([[NSFileManager defaultManager] fileExistsAtPath:[url path]])
{
[doc openWithCompletionHandler:^(BOOL success)
{
// Run completion block
completionBlock(doc);
} ];
}
else
{
// Save temporary document to documents directory
[doc saveToURL:url
forSaveOperation:UIDocumentSaveForCreating
completionHandler:^(BOOL success)
{
// Run compeltion block
completionBlock(doc);
}];
}
}
そして、viewDidLoadで呼び出されます:
if (!self.lgtbDatabase) {
[ManagedDocumentHelper openDocument:@"DefaultLGTBDatabase" UsingBlock:^(UIManagedDocument *document){
[self useDocument:document];
}];
}
useDocumentは、self.documentを提供されたドキュメントに設定するだけです。
このコードを変更して、データが別のスレッドに挿入され、ユーザーがボタンをクリックしてセクションを表示できるようにします。データのインポートによってUIがハングすることはありません。
私がこの問題に数日間取り組んできて、ここにある他の同様の質問があっても、それを解決することができなかったので、どんな助けでもありがたいです。他に必要な情報がありましたら、お知らせください。
ありがとうございました
編集:
これまでのところ、この質問は1票の反対票を獲得しています。この質問を改善する方法がある場合、または誰かが私が見つけられなかった質問を知っている場合、方法または場所についてコメントしていただけますか?あなたが反対票を投じる別の理由がある場合は、私は否定性を理解することができず、より良い貢献をする方法を学びたいので、私に知らせてください。