2016年1月7日 星期四

iOS筆記:NSURLSession for ftp requests (2) 和一個EXC_BAD_ACCESS紀錄

標題真長。
聽說NSURLSession的 download, upload request只針對HTTP,不知改了沒
先不提這個,來研究apple 的 FTP sample




我只是異想天開的要把download的部分拆出來封裝成一個class以便日後能直接取用,沒想到一把繼承從UIView(對沒錯拆成一個顯示資訊兼下載的 view也work)改成NSobject ,NSStreamDelegate直接失效,更準確來說是runLoop完之後不知道跑去哪了
沒有Delegate我是要從哪裡得到bytes啊!

NOTE 1:
在stackoverflow看到了NSStreams Crashing Program!,看到那個最佳解我都傻了
"When I placed this in my View Controller (and not in a separate class) it worked perfectly"
(請容我用放大字體來表現我內心的吶喊:就是想拆出來不然早就放在view裡了事!)

NOTE 2:
放在View Controller,RunLoop在thread1(main thread)跑
獨立class,在thread 5 跑(Thread 5Queue : NSOperationQueue 0x15d6fea0 :: NSOperation 0x15e59850 (QOS: LEGACY) (serial))
那就移去main thread執行不就好了?下場就是:
EXC_BAD_ACCESS

NOTE 3:
根據經驗,90%以上發生原因都在引用被釋放或者是nil的物件發生的
去Product> Scheme > Edit Scheme> Run - Diagnostic>勾選Enable Zombie Object
然後重新Run一次,得到log:
2016-01-07 18:10:44.137 FTPDemo[1645:1197716] *** -[ftpDownloadTask respondsToSelector:]: message sent to deallocated instance 0x15eadfa0

然後看看自己的code:

{
    ......
    ftpDownloadTask *newTask = [[ftpDownloadTask alloc] initWithItems:@[[result lastObject]]];
    [newTask startDownload];
}

newTask是個local variable,過了這個方法記憶體就被釋放。
所以,delegate找不到目標。(delegate在ftpDownloadTask裡面)

於是class中加了一個 ftpDownloadTask的property,把newTask替換成它,再Run一次⋯⋯
delegate開工了!可喜可賀!

可以理解為何在 View Controller 還是View上可以work,因為這個物件只要還在螢幕上就不會被釋放。

至於不放在main thread為何不會出現EXC_BAD_ACCESS這個有待發現。
BTW,  Enable Zombie Object 用完後記得要關起來

NOTE 4:
把mainThread換成CurrentThread後它又不知道跑到哪裡去了。
這樣要如何才能讓它在其他thread執行下載動作?

NOTE 5:
忘記把中斷點拔掉,於是拔了繼續run⋯⋯
2016-01-07 18:47:26.053 FTPDemo[1678:1201066] [FtpDownloadTask] Stream open error:
The operation couldn’t be completed. Socket is not connected (Code = 57)
停太久斷線了。


沒有留言:

張貼留言