سؤال

أواجه هيك من الوقت مع شيء يبدو بالأحرى
مباشرة لكنني لا أستطيع أن أحصل على العمل. أنا بناء
تطبيق iPhone الذي يسترجع البيانات من مضيف الويب. أنا أحاول
إنشاء اتصال غير متزامن للمضيف كما أريد أن أبقى
يتم تحرير الجهاز أثناء الاتصال. (sendsynchronousrequest تجمد
الهاتف حتى يتم الطلب.) هنا هو رمز الاتصال الخاص بي:

//temp url to see if data is returned:
NSURL *theURL = [NSURL URLWithString:@"http://www.theappleblog.com/feed"];

NSURLRequest *dataRequest = [NSURLRequest requestWithURL:theURL
             cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
             timeoutInterval:60];

/* establish the connection */  
theConnection = [[NSURLConnection alloc]
                 initWithRequest:dataRequest
                        delegate:self
                startImmediately:YES];

if (theConnection == nil) { 
    NSLog(@"Connection Failure!");
    self.urlData = nil; 
} else {
    self.urlData = [[NSMutableData data] retain];   
}

لدي كل أساليب المندوب المناسبة التي تم إعدادها:

-(void)connection:(NSURLConnection *)connection
       didReceiveResponse:(NSURLResponse*)response
{
    [urlData setLength:0];
    UIApplication *application = [UIApplication sharedApplication];
    application.networkActivityIndicatorVisible = YES;
    NSLog(@"Received Response!");
}

-(void)connection:(NSURLConnection *)connection
       didReceiveData:(NSData*)incrementalData
{
    [self.urlData appendData:incrementalData];

    NSNumber *resourceLength = [NSNumber
              numberWithUnsignedInteger:[self.urlData length]];
    NSLog(@"resourceData length: %d", [resourceLength intValue]);
    NSLog(@"filesize: %d", self.urlDataSize);
    NSLog(@"float filesize: %f", [self.urlDataSize floatValue]);
}

-(void)connectionDidFinishLoading:(NSURLConnection*)connection
{
    NSLog(@"Connection finished loading\n");
    NSLog(@"Succeeded! Received %d bytes of data",[urlData length]);
    _isFinished = YES;
    UIApplication *application = [UIApplication sharedApplication];
    application.networkActivityIndicatorVisible = NO;
}

- (void)connection:(NSURLConnection *)connection
        didFailWithError:(NSError *)error
{
    NSLog(@"Error: %@",[error localizedDescription]);
}

كما ترون، لدي حمولة قارب من رسائل السجل لأنني أردت
لمعرفة ما إذا اي شى كان قادما على الإطلاق. اختبار اتصال بلدي
يعود كن صحيحا ولكن لا يتم تحميل بيانات. كما قلت، أنا متأكد
يجب أن أفعل (أو لا تفعل) شيء ما حقا غبي. ولكن ماذا؟
أي مساعدة سيكون أكثر تقدير.

شكرا، لورنس

هل كانت مفيدة؟

المحلول

هذا لا يجيب على سؤالك مباشرة، ولكن قد تفكر في النظر في بن كأسي ASIHTTPRequest مكتبة، والتي يلف حولها CFNetwork الفصول وتشمل رمز الطلب غير المتزامن الخيوط الذي يأخذ الكثير من العمل من القيام بذلك بشكل صحيح.

نصائح أخرى

كانت المشكلة هي أنني كنت مستمرا في تدفق البرنامج وعدم التوقف للسماح بالاتصال بإنهاء التنزيل. شكرا لك على كل الاقتراحات.

بعض الاقتراحات:

  • في مقتطفك الأول، بدلا من theConnection حاول التعيين إلى self.theConnection للتأكد من استدعاء أساليب ملحق العقارات. في أماكن مختلفة كما تقاطع self.urlData و urlData. وبعد قد ترغب في جعلهم جميعا متسقة من خلال المرور self.

  • قد ترغب في جعل dataRequest خاصية كذلك وتذهب من خلال self للتأكد من أنها تحتفظ بها.

  • self.urlData = [[NSMutableData data] retain]; - يجب أن لا تحتاج إلى الاحتفاظ الإضافي. يعبر من خلال self يفعل ذلك بالنسبة لك. الاحتفاظ الإضافي سيجعله الكائن سوف يتمسك بالتسرب والتسرب حتى عندما يتم كل شيء.

  • في ملاحظة ذات صلة، تأكد من طباعة عدد الاحتفاظ به لكل كائن. أيضا، قد ترغب في الحصول على روتين تنظيف عام حولها لإطلاق هذه الهياكل (أو مجموعات self.foo = nil) لذلك في أي وقت إذا كان barfs خارج، يمكنك الاتصال بالروتين للحصول على أشياء تنظيفها.

  • احصل على نسخة من Charles أو Wireshark (أو تشغيل Tcpdump في وحدة التحكم) ومشاهدة حركة مرور الشبكة. سوف يساعد في تحديد المرحلة في التدفق في التدفق.

الفكر الأولي - هو الكائن الذي يتم الاحتفاظ به كل هذا الرمز بشكل صحيح؟ قد يتم إصدارها، وبالتالي تلامل الاتصال ...

وإلا يجب عليك أن ترى على الأقل الاستجابة.

لا شيء من الواضح أنه هناك خطأ هناك. لدي رمز هو نفسه بشكل كبير ويعمل بشكل جيد. الاختلافات الوحيدة التي أراها هي:

  • يمكنني استخدام nsurlrequestuseprotoculcachepolicy بدلا من nsurlrequestreloadignoringlocalcachedata

  • يمكنني استخدام الاتصال = [[nsurlconnection alloc] interwithrequest: مندوبها: الذات]؛ بدلا من تحديد starmimedIly: نعم (لأنه الافتراضي)

سيكون من المفيد معرفة أي أساليب المندوبين الخاصة بك، إن وجدت. على الأقل، يجب أن تحصل على واحد على الأقل أو آخر من ConnectionDIdfinishload أو ConnectionDidfail التي يتم استدعاؤها. إذا لم يكن الأمر كذلك، فمن المحتمل أن يكون هناك خطأ ما في إعداد مندوبك - هل أنت متأكد تماما من أن توقيعات طريقة المندوب صحيحة، وأنك تمر في البند المناسب باعتباره المندوب؟

من الصعب صفر في أي شيء لأنه غير واضح من سؤالك الذي ينفذ أي من عبارات NSLOG. يرجى أن تكون أكثر وضوحا قليلا حول النتائج التي تحصل عليها.

من نظرة سريعة على الشيء الوحيد الذي يشبه مشكلة محتملة هو أن لديك حالة سباق عند إعداد الاتصال. إذا كانت الشبكة سريعة بشكل خاص، فهناك فرصة ضئيلة ولكن غير صفرة بأنك على النحو التالي: سيتم استدعاء DidreceiveiveiveData: قبل تخصيص Self.Urldata. أود أن أقترح تخصيص Urldata إما قبل بدء الاتصال أو في -Connection: didreceiveresponse: لمنع هذا.

إذا لم يصل ذلك، فإن هناك حاجة إلى مزيد من المعلومات منك.

أنت تقول هذا الرمز يعمل بشكل جيد باستخدام الطريقة غير المتزامنة؟ اختبار عنوان URL هذا، فإنه يعيد توجيه إلى آخر، فماذا إذا قمت بتنفيذ أساليب مندوب إعادة التوجيه؟ ماذا لو حاولت بعض عناوين URL مختلفة؟

هل التطبيق يستجيب خلاف ذلك؟ هل تشغيل Runloop؟ ماذا يفعل التطبيق بعد بدء الطلب - هل يعود من معالج الأحداث إلى Runloop؟ (إذا لم يكن الأمر كذلك، فلن تحصل أبدا على أي من عمليات الاتصال الخاصة بك، لأنها تسليمها عبر RunLoop.)

تم تصميم NSurlConnection للعمل مع أي نوع من البروتوكول، وليس فقط HTTP. هذا يعني أن الاتصال: ديدفيل: يسمى Witherror الإتصال أخطاء، ولكن ليس ل بروتوكول أخطاء. أنت لا تتحقق من أخطاء البروتوكول - عليك أن تلتقطها في اتصال: didreceiveresponse :. الحيلة هي أن كائن الاستجابة الذي تم تمريره هو في الواقع كائن nshttpurlresponse. إذا قمت بالتحقق من Statuscode للاستجابة، فسوف أراهن أنك تحصل على خطأ HTTP مثل 404 أو Server 500.

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