2016-05-14 16 views
3

私は間違って何をしていますか?事前にあなたの助けをありがとう!UnsafeMutablePointerエラーが発生するのはなぜですか?

データベースへのリクエストを制御する目的で、またデータを解析するために外部のウェブサイトに次のコードを書きました。目標は、1000以上のリクエストを生成してスタックに配置し、同時に複数のリクエストが同時に発生する回数を制限することでした。これは非常にうまく動作しますが、すべてはそれほど頻繁には、このコードの行に例外を生成します?

RequestManager.requests .append(!_request)

このコード行は、プッシュ機能WebRequestManagerです。以下のコードを見ることができます。

致命的なエラー:負の数とUnsafeMutablePointer.destroy

は、例えば、要求は次のようになります。

class WebRequest 

{

private var trials = 0 

private var executed = false 

private var data : AnyObject? 

private var url : String? 

private var completion : ((data: NSData?, response: NSURLResponse?, error : ErrorType?) -> Void)? 

private func execute() 
{ 
    if !executed 
    { 
     trials += 1 
     self.executed = true 
     let endpoint = NSURL(string: url!) 

     if (endpoint == nil) { return } 

     let request = NSMutableURLRequest(URL: endpoint!) 

     if data != nil 
     { 
      if data is NSData 
      { 
       request.HTTPMethod = "POST" 
       request.HTTPBody = data as? NSData 
      } 
      else 
      { 
       request.HTTPMethod = "POST" 
       request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(data!, options: []) 
      } 
     } 
     request.addValue("application/json", forHTTPHeaderField: "Content-Type") 
     request.addValue("application/json", forHTTPHeaderField: "Accept") 

     let task = NSURLSession.sharedSession().dataTaskWithRequest(request) 
     { 
      data, response, error in 

      if error == nil 
      { 

       WebRequestManager.pop() 

       self.completion?(data: data,response: response,error: error) 
      } 
      else 
      { 
       if self.trials < 10 
       { 
        self.executed = false 
        self.execute() 
       } 
       else 
       { 
        WebRequestManager.pop() 
        self.completion?(data: data,response: response,error: error) 
       } 
      } 
     } 
     task.resume() 
    } 
} 

init(_query : Query?) 
{ 

    data = _query!.data 

    url = _query!.toString() 
} 

init(_data : AnyObject?, _url : String) 
{ 

    data = _data 

    url = _url 
} 

init(_data : NSData?, _url : String) 
{ 
    data = _data 
    url = _url 
} 

deinit 
{ 
    completion = nil 
    data = nil 
    url = nil 
} 

WebRequestManager.Request(WebRequest(_data: self.beerstores, _url: "http://brewskibooze.com/beerstore/build_database/postbeerstoreproductavailability.php"), 
            completion: { 
             (data,response,error) in 
             if error == nil 
             { 
              self.display(_string: "Process Complete") 
             } 
             else 
             { 
              self.display(_string: "Unable to post inventory.") 
             } 


            }) 

ここでコードがあります210

}

class WebRequestManager 

{

private var requests : [WebRequest]? 
private static var MaxConcurrentRequests = 10 

private var currentRequestCount = 0 

private static var RequestManager = WebRequestManager() 

private class var RequestCount : Int 
{ 
    return RequestManager.currentRequestCount 
} 

private class func DecrementCount() 
{ 
    RequestManager.currentRequestCount -= 1 
} 

private class func IncrementCount() 
{ 
    RequestManager.currentRequestCount += 1 
} 

private class func push(_request : WebRequest?) 
{ 
    if _request != nil 
    { 
     IncrementCount() 
     RequestManager.requests?.append(_request!) 
    } 

} 

private class func pop() 
{ 
    if RequestManager.requests?.count > 0 
    { 
     let last : WebRequest? = RequestManager.requests?.removeLast() 
     if last != nil 
     { 
      last!.execute() 
      DecrementCount() 
     } 
    } 
} 

init() 
{ 
    requests = [WebRequest]() 
} 

class var ActiveThreadCount : Int 
{ 
    return RequestManager.currentRequestCount 
} 


class func Request(_request : WebRequest?,completion : ((data: NSData?, response: NSURLResponse?, error : ErrorType?) -> Void)?) 
{ 
    _request?.completion = completion 
    if RequestCount < MaxConcurrentRequests 
    { 
     _request?.execute() 
    } 
    push(_request) 
} 

}

+0

をDebugerはでどのラインを停止したのですか?そしてあなたのコードはとても長いです... – Lumialxk

+0

申し訳ありませんが、長いコードについて。私は問題の記述で徹底しようとしていました。 WebRequestManager RequestManager.requestsのpush()関数で終了しますか?.append(_request!) – bhardy

+0

同時にポップしてプッシュしている位置に自分自身があるプッシュとポップを含む複数のリクエストがある可能性はありますか?どうすれば問題を回避できますか? – bhardy

答えて

0

私はかなり確信して、私は自分の質問に答えました。問題は、これらの多くの要求と多くのポップとスレッド環境での要求のプッシュでは、同時ポップとプッシュのリスクがあるということです。

objc_sync_enter(ロック)ここ

objc_sync_exit(ロック)

クレジット原因:この警告が発生し

Create thread safe array in swift

しかし、...

ソリューションは、このように見えます

| synchronize-skip |フェンスがスナップショットブロック内で開始されました - ワークスペースをスキップするとfenceExemptQueueからメッセージをデキューし、スナップショットが発生しないと予想されるので同期します 2016-05-14 14:11:57.791 _____ [348:99565] | synchronize - スキップ|フェンスは、スナップショットブロックの内部で開始された - それはfenceExemptQueueからメッセージをデキュー可能性があるため、ワークスペースは同期スキップとスナップショットは、あなたが正しい方向に私を指摘

0

を発生することはないことを期待して、シリアルディスパッチキューは、私の問題を解決しました警告なし。

が迅速に3シリアルディスパッチキューを作成します。

let serialQueue = DispatchQueue(label: "myqueue")` 

次にキューに配列を変更:

serialQueue.sync { 
     //modify array 
    } 
関連する問題