一點一滴,編程人生

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            69 隨筆 :: 0 文章 :: 25 評論 :: 0 Trackbacks

          就個人經(jīng)驗而言,在iphone線程中使用異步NSURLConnection的經(jīng)驗可以說是一個完全和愉悅搭不上邊的事情。他給我?guī)淼穆闊┛烧娌簧佟@纾皫滋?,幫客戶定位一個問題的時候發(fā)生的事情。

          事情經(jīng)過是這樣的:客戶反饋,無法正常使用我們提供的某個和網(wǎng)絡(luò)相關(guān)的功能,網(wǎng)絡(luò)回調(diào)沒有收到。但是其他回調(diào)可以正常工作,并且所有回調(diào)都是以同樣的邏輯放在某個地方的。

          我先確認(rèn)了他的使用方式是否正確,并確認(rèn)了輸入?yún)?shù)的正確性,并且驗證了回調(diào)的正確設(shè)置以及回調(diào)函數(shù)的使用無誤。一切都沒有問題,但是就是無法收到回調(diào)。

          一切都那么的神奇,功能的調(diào)用并沒有什么特殊的,但是就單單這個功能工作不正常。中間又經(jīng)過一些確認(rèn),發(fā)現(xiàn)數(shù)據(jù)并沒有到達服務(wù)端。但是同樣的使用方式在我們自己的環(huán)境下工作又是正常的。

          花了將近5個小時,還是沒有發(fā)現(xiàn)原因,就在我準(zhǔn)備放棄的時候,突然想到,莫非他的調(diào)用位置是線程中調(diào)用?經(jīng)過確認(rèn),發(fā)現(xiàn)果然是在線程中調(diào)用的!讓他們使用performOnMainThread的方式調(diào)用,終于解決了問題。

          以前遇到過一次在線程中調(diào)用異步網(wǎng)絡(luò)的情況,請教同事,同事告知,異步網(wǎng)絡(luò)需要自己的RunLoop,所以要在線程中使用異步網(wǎng)絡(luò)必須有自己的RunLoop,可以將他放到主線程的RunLoop。

          但是,這樣子,多線程的性能必然被降低,因為這樣網(wǎng)絡(luò)的工作就都是在主線程中完成的。同時懷疑,這樣子的網(wǎng)絡(luò)性能設(shè)計不是很低下!

          剛好有點時間,就仔細(xì)的翻了一下蘋果的開發(fā)文檔,發(fā)現(xiàn)其中指出,所有的NSThread都有一個屬于自己的NSRunLoop,而NSURLConnection的回調(diào)都會回調(diào)到當(dāng)前線程中!

          這個和我目前遇到的完全不一樣!我無法在當(dāng)前線程中收到回調(diào)!

          又仔細(xì)在網(wǎng)絡(luò)上搜索之后發(fā)現(xiàn),原來,是因為網(wǎng)絡(luò)回調(diào)的時候線程的NSRunLoop已經(jīng)被無效的原因。

          我們常見的線程中網(wǎng)絡(luò)調(diào)用是這樣的:

          - (void)threadFunc
          {
          NSAutoReleasePool *pool = [NSAutoReleasePool new];
          //do something
          ……

          //send your request
          [NSURLConnection connectionWithRequest:xxx];

          //do some other thing
          ……
          [pool release];
          }

          一般來說,這個函數(shù)會很快走完,線程就結(jié)束了。所以,當(dāng)網(wǎng)絡(luò)響應(yīng)回來的時候,你的線程已經(jīng)結(jié)束了。你的網(wǎng)絡(luò)回調(diào)依賴于該線程的NSRunLoop,但是線程已經(jīng)結(jié)束了,所以你的網(wǎng)絡(luò)回調(diào)就無法收到!!同理,所有的performAfterDelay之類的api以及NSTimer的在線程中工作都不正常!

          那么,該如何讓他正常工作呢?很簡單,做完事情之前,讓線程不要結(jié)束,保持空轉(zhuǎn)狀態(tài)就行了。

          - (void)threadFunc
          {
          NSAutoReleasePool *pool = [NSAutoReleasePool new];
          //do something
          ……

          //send your request
          [NSURLConnection connectionWithRequest:xxx];

          //do some other thing
          ……

          while(shouldExit)
          {
          [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
          }
          [pool release];
          }

          posted on 2012-07-25 11:14 writegull 閱讀(1979) 評論(1)  編輯  收藏 所屬分類: iphone

          評論

          # re: iphone線程中使用異步網(wǎng)絡(luò)的悲催經(jīng)歷 2016-07-07 13:48 acc
          用AFNetworking就省去這些麻煩了  回復(fù)  更多評論
            

          主站蜘蛛池模板: 泊头市| 肇州县| 麻阳| 潞西市| 澎湖县| 贵阳市| 和顺县| 宣恩县| 阿拉尔市| 宝鸡市| 岳普湖县| 合肥市| 金乡县| 勐海县| 阜康市| 长沙市| 福州市| 平舆县| 保靖县| 苍南县| 巴东县| 东源县| 潢川县| 甘南县| 平泉县| 镇坪县| 齐河县| 昔阳县| 广南县| 绥棱县| 保德县| 宣威市| 锦屏县| 穆棱市| 仲巴县| 禄劝| 吉隆县| 台东县| 北票市| 长岛县| 广安市|