سؤال

لدي فصل يقوم بتحديث ملفين .plist في دليل مستندات التطبيق عبر NSURLConnection.يعمل الفصل كمفوض خاص به لـ NSURLConnection.إنه يعمل بشكل صحيح عندما أطلب ملفًا واحدًا، ولكنه يفشل عندما أحاول تحديث ملفين.هل يبدو أنني يجب أن أبدأ موضوعًا جديدًا لكل رسالة من رسائل getNewDatabase؟

- (void)getAllNewDatabases {
    [self performSelectorOnMainThread:@selector(getNewDatabase:) withObject:@"file1" waitUntilDone:YES];
    [self performSelectorOnMainThread:@selector(getNewDatabase:) withObject:@"file2" waitUntilDone:YES];
}

- (BOOL)getNewDatabase:(NSString *)dbName
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSMutableString *apiString = [[NSMutableString alloc] initWithString:kAPIHost];
    [apiString appendFormat:@"/%@.plist",dbName];
    NSURLRequest *myRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:apiString] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
    NSURLConnection *myConnection = [[NSURLConnection alloc] initWithRequest:myRequest delegate:self];
    [apiString release];
    if( myConnection )
    {
        //omitted for clarity here
    }
    [pool release];
}
//NSURLConnection delegate methods here ...
هل كانت مفيدة؟

المحلول

ولقد وجدت شيئا للاهتمام مع NSURLConnection وNSThread - فإن موضوع يعيش فقط طالما أنه يأخذ لأداء الطريقة التي يمكنك استدعاء منه.

في الحالة أعلاه الخيط سوف يعيش فقط طالما getNewDatabase:(NSString *)dbName يستغرقه لإكمال، وبالتالي وأد كل أساليب مندوبها قبل أن يكون فعلا الوقت لفعل أي شيء.

ولقد وجدت هذا الموقع أن يعطي تفسيرا أفضل وإيجاد حل لمشكلة

وأنا أنب قليلا حتى أتمكن من لديهم الوقت المخصص ما اذا كان لم يكمل في إطار زمني معين (سهل عندما يقوم شخص ما يتجول بين نقاط الوصول)

    start = [NSDate dateWithTimeIntervalSinceNow:3];

    while(!isFinished && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
                                                  beforeDate:[NSDate distantFuture]]){

    if([start compare:[NSDate date]] == NSOrderedAscending){
        isFinished = YES;
    }
}

نصائح أخرى

كما هو الحال حاليًا في الكود الذي قدمته، getNewDatabase: يعمل على الموضوع الرئيسي للتطبيق الخاص بك.المشكلة في هذه الحالة بالذات هي شيء آخر غير دورة حياة الخيط، كما لاحظ جيمس في حالته.

إذا كنت تنوي إجراء هذه العملية في الخلفية، فإنني أوصي بالنظر في استخدام NSOperationQueue و NSOperation بدلاً من حل المشكلة بالرمز الحالي.أعتقد أن قضيتك مناسبة تمامًا NSOperationQueue, ، خاصة وأن لديك أكثر من مهمة تنزيل واحدة للقيام بها.

ديف دريبين لديه مقالة ممتازة حول استخدام واجهة برمجة التطبيقات غير المتزامنة، مثل NSURLConnection، داخل ملف NSOperation.وبدلاً من ذلك، طالما أنك تعمل في سلسلة محادثات في الخلفية، يمكنك أيضًا تبسيط العملية واستخدام طريقة API متزامنة بدلاً من ذلك في NSOperation الخاص بك، مثل initWithContentsOfURL:.

ماركوس زارا كذلك كتب البرنامج التعليمي يوضح ذلك مدى سهولة دمج واستخدام NSOperationQueue لعمليات الخلفية البسيطة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top