2016-01-15 12 views
9

पर वापस प्रेषण करें तो मेरे पास एक ऐसा एप्लिकेशन है जो असीमित घटनाओं की एक श्रृंखला को सक्रिय करता है और फिर परिणाम को बफर में लिखता है। समस्या यह है कि मैं बफर तुल्यकालिक को लिखे जाने कीस्विफ्ट 2 - आईओएस - मूल थ्रेड

कंकाल कोड के रूप में इस तरह के

let Session = NSURLSession.sharedSession() 
let TheStack = [Structure]() 
//This gets called asynchronously, e.g. in threads 3,4,5,6,7 
func AddToStack(The Response) -> Void { 
    TheStack.insertAt(Structure(The Response), atIndex: 0)) 
    if output.hasSpaceAvailable == true { 
     // This causes the stream event to be fired on mutliple threads 
     // This is what I want to call back into the original thread, e.g. in thread 2 
     self.stream(self.output, handleEvent: NSStreamEvent.hasSpaceAvailable) 
    } 
} 

// This is in the main loop, e.g. thread 2 
func stream(aStream: NSStream, handleEvent: NSStreamEvent) { 

    switch(NSStreamEvent) { 

     case NSStreamEvent.OpenCompleted: 
      // Do some open stuff 
     case NSStreamEvent.HasBytesAvailable: 
      Session.dataTaskWithRequest(requestFromInput, completionHandler: AddToStack) 
     case NSStreamEvent.HasSpaceAvailable: 
      // Do stuff with the output 
     case NSStreamEvent.CloseCompleted: 
      // Close the stuff 
    } 
} 

समस्या है (धागा कि अतुल्यकालिक प्रक्रिया पैदा में) चाहते धागा कि कॉल dataTaskWithRequest में है है धागा, कहते हैं, कई अलग अलग धागे में 3. पूरा होने हैंडलर आग और case NSStreamEvent.HasSpaceAvailable: का कारण बनता है धागा 3 में चल रहा हो सकता है, के साथ साथ सभी धागे कि वे में ही अस्तित्व में

मेरे सवाल यह है:। मैं इसे कैसे कर सकता हूँ ताकि self.stream(self.output, handleEvent: NSStreamEvent.hasSpaceAvailable) है थ्रेड 3 में कहा जाता है, या कभी भी मूल धागा डब्ल्यू आउटपुट चरण में एक-दूसरे के इस ट्रिपिंग को रोकने के लिए।

अग्रिम धन्यवाद!

नोट: धागा है कि इनपुट/आउटपुट हैंडलिंग शामिल NSThread.detachNewThreadSelector

साथ बनाया गया था
+2

अपनी खुद की कतार बनाने के बारे में और अपने लेखक को उपयोग करने वाले व्यक्ति को कैसे पास किया जाए? (मैं कहता हूं "कतार" क्योंकि आपने gcd के साथ टैग किया है।) –

+1

मैंने काम छोड़ने से लगभग 5 मिनट पहले ऐसा करने के बारे में सोचा था। थ्रेड/कतार बनाएं और उसमें सभी आउटपुट फनल करें। इस तरह यदि यहां कई धागे बुला रहे हैं, तो वे सभी एक बार निष्पादित करने की कोशिश नहीं कर रहे हैं। मैं अब मंगलवार तक बंद हूं इसलिए यदि वह मार्ग है तो मैं आपको बता दूंगा कि यह कैसे जाता है – Ajwhiteway

+0

मेरे पास पहले से ही NSThread.detachNewThreadSelector द्वारा बनाई गई NSThread है। यह वह धागा है जिसे मुझे वापस कॉल करने की आवश्यकता है। मुझे डर है कि प्रेषण वास्तव में समस्या को खराब कर सकता है (सबकुछ समाप्त होने से पहले बंद होने वाली धाराएं) – Ajwhiteway

उत्तर

6

ठीक है, सवाल करने के लिए टिप्पणी से उत्सुक दर्शक मैं, सहायता के साथ के लिए मैं पता लगा है कि मैं क्या मूल रूप से कैसे करना है प्रश्न में पूछा गया है कि क्या यह अंततः जीसीडी का उपयोग करने के लिए फिर से लिखा गया है, एक अलग सवाल है)

समाधान (कोड में थोड़ा बढ़ाया गुंजाइश के साथ) एक विशिष्ट थ्रेड के साथ प्रदर्शन चयनकर्ता का उपयोग करना है।

final class ArbitraryConnection { 

internal var streamThread: NSThread 

let Session = NSURLSession.sharedSession() 
let TheStack = [Structure]() 
//This gets called asynchronously, e.g. in threads 3,4,5,6,7 
func AddToStack(The Response) -> Void { 
    TheStack.insertAt(Structure(The Response), atIndex: 0)) 
    if output.hasSpaceAvailable == true { 
     // This causes the stream event to be fired on multiple threads 
     // This is what I want to call back into the original thread, e.g. in thread 2 

     // Old way 
     self.stream(self.output, handleEvent: NSStreamEvent.hasSpaceAvailable) 
     // New way, that works 
     if(streamThread != nil) { 
      self.performSelector(Selector("startoutput"), onThread: streamThread!, withObject: nil, waitUntilDone: false) 
     } 
    } 
} 

func open -> Bool { 
    // Some stuff 
    streamThread = NSThread.currentThread() 
} 


final internal func startoutput -> Void { 
    if(output.hasSpaceAvailable && outputIdle) { 
     self.stream(self.output, handleEvent: NSStreamEvent.HasSpaceAvailable) 
    } 
} 
// This is in the main loop, e.g. thread 2 
func stream(aStream: NSStream, handleEvent: NSStreamEvent) { 

    switch(NSStreamEvent) { 

     case NSStreamEvent.OpenCompleted: 
      // Do some open stuff 
     case NSStreamEvent.HasBytesAvailable: 
      Session.dataTaskWithRequest(requestFromInput, completionHandler: AddToStack) 
     case NSStreamEvent.HasSpaceAvailable: 
      // Do stuff with the output 
     case NSStreamEvent.CloseCompleted: 
      // Close the stuff 
    } 
} 
} 

तो चयनकर्ता के साथ वस्तु पर performSelector का उपयोग करें और onThread का उपयोग यह बताने के लिए कि धागा करने के लिए पारित करने के लिए। मैं चयनकर्ता करने से पहले और कॉल करने से पहले दोनों को जांचने से पहले यह सुनिश्चित करने के लिए कि आउटपुट में जगह उपलब्ध है (सुनिश्चित करें कि मैं अपने आप पर यात्रा नहीं कर रहा हूं)

+0

मैं 'प्रदर्शन चयनकर्ता' के साथ रहूंगा, क्योंकि यह जीसीडी को लपेटता है, और समान या अलग कतारों से प्रेषण के आसपास conundrums हल करता है। ब्याज की प्रतीक्षा है 'इंतजार न करें: गलत', जिसे मैं आम तौर पर संचालन के उचित अनुक्रमण सुनिश्चित करने के लिए 'सच' होना पसंद करता हूं। – SwiftArchitect

+0

हाँ, मैंने अभी भी 'प्रदर्शन चयनकर्ता' के साथ परीक्षण के लिए प्रोजेक्ट को लपेट लिया है। इन स्पॉन के कारण, आम तौर पर प्रति थ्रेड केवल एक होता है ('डेटा टास्कविथरक्वेट' हैडल करता है)। तो इसे 'झूठा' बनाकर मैं बफर के लिए कतार में डेटा जोड़ने के बाद थ्रेड को साफ़ करने की अनुमति दे रहा हूं। बड़ी परियोजना में डालते समय सब कुछ एक साथ हो रहा है यह सुनिश्चित करने के लिए अभी भी कुछ परीक्षणों के माध्यम से जाना है। – Ajwhiteway

+0

आप पूर्ण नियंत्रण में लग रहे हैं! 'प्रदर्शन चयनकर्ता' और 'प्रदर्शनब्लॉक' के साथ मेरा अनुभव यह है कि मुझे आम तौर पर यहां और वहां मिलीसेकंड सहेजने का अफसोस है, और मजबूती और भविष्यवाणी के लिए 'प्रतीक्षा करें नहीं' और 'प्रदर्शनब्लॉक एंड वाइट' पर वापस जाना चाहिए। – SwiftArchitect

1

यह मुझे उपरोक्त धागे पर टिप्पणी नहीं करेगा (यह है जो मुझे छिपाने के लिए मिलता है), लेकिन एक बात यह जानना है कि यदि आपका waitUntilDone या performBlockAndWait का उपयोग करता है तो आपका वर्तमान कोड आपके यूआई को डेडलॉक कर सकता है।

यदि आप उस मार्ग पर जाते हैं तो आपको पूरी तरह से यह सुनिश्चित करने की आवश्यकता है कि आप इसे मुख्य थ्रेड से नहीं बुलाएं या फॉलबैक केस है जो एक नए धागे को जन्म देता है।

+0

यह एक अच्छा मुद्दा है कि मैंने अपने कोड में संभाल नहीं की है, मेरे मामले में 'डेटा टास्कविथरक्वेट' के पूर्ण होने वाले हैंडलर को मुख्य जीयूआई थ्रेड के अंदर कभी खत्म नहीं होना चाहिए। किसी भी मामले में एक अच्छा बिंदु। चूंकि आप सवाल का जवाब देने के लिए खुद के अलावा एकमात्र व्यक्ति थे, इसलिए बक्षीस इनाम का आनंद लें! – Ajwhiteway

संबंधित मुद्दे