मैंने स्विफ्ट में बहुत अधिक नहीं पढ़ा है, लेकिन एक बात जो मैंने देखी है कि कोई अपवाद नहीं है। तो वे स्विफ्ट में त्रुटि से निपटने के लिए कैसे करते हैं? क्या किसी को त्रुटि से संबंधित कुछ भी मिला है?
मैंने स्विफ्ट में बहुत अधिक नहीं पढ़ा है, लेकिन एक बात जो मैंने देखी है कि कोई अपवाद नहीं है। तो वे स्विफ्ट में त्रुटि से निपटने के लिए कैसे करते हैं? क्या किसी को त्रुटि से संबंधित कुछ भी मिला है?
जवाबों:
स्विफ्ट 2 में चीजें थोड़ी बदल गई हैं, क्योंकि एक नया त्रुटि-हैंडलिंग तंत्र है, यह कुछ हद तक अपवादों के समान है लेकिन विस्तार से अलग है।
यदि फ़ंक्शन / विधि यह इंगित करना चाहती है कि यह एक त्रुटि फेंक सकता है, तो इसमें throws
इस तरह कीवर्ड होना चाहिए
func summonDefaultDragon() throws -> Dragon
नोट: फ़ंक्शन वास्तव में फेंक सकता है इस प्रकार की त्रुटि के लिए कोई विनिर्देश नहीं है। यह घोषणा केवल यह बताती है कि फ़ंक्शन किसी भी प्रकार के त्रुटिटाइप को लागू करने का एक उदाहरण फेंक सकता है या बिल्कुल भी नहीं फेंक रहा है।
फ़ंक्शन को इनवॉइस करने के लिए, आपको इस तरह का प्रयास करना होगा
try summonDefaultDragon()
इस लाइन को आम तौर पर इस तरह के कैच-ब्लॉक को पेश करना चाहिए
do {
let dragon = try summonDefaultDragon()
} catch DragonError.dragonIsMissing {
// Some specific-case error-handling
} catch DragonError.notEnoughMana(let manaRequired) {
// Other specific-case error-handlng
} catch {
// Catch all error-handling
}
नोट: पकड़ खंड स्विफ्ट पैटर्न के सभी शक्तिशाली विशेषताओं का उपयोग करते हुए मिलान करते हैं ताकि आप यहां बहुत लचीले हों।
आप त्रुटि को प्रचारित करने का निर्णय ले सकते हैं, यदि आप एक ऐसे फ़ंक्शन से एक फेंकने वाले फ़ंक्शन को बुला रहे हैं जो स्वयं throws
कीवर्ड के साथ चिह्नित है :
func fulfill(quest: Quest) throws {
let dragon = try summonDefaultDragon()
quest.ride(dragon)
}
वैकल्पिक रूप से, आप फेक फंक्शन का उपयोग करके कॉल कर सकते हैं try?
:
let dragonOrNil = try? summonDefaultDragon()
इस तरह से आपको या तो रिटर्न वैल्यू मिलती है या शून्य, अगर कोई त्रुटि हुई है। इस तरह से इस्तेमाल करने से आपको एरर ऑब्जेक्ट नहीं मिलता है।
जिसका अर्थ है कि आप try?
उपयोगी कथनों के साथ भी संयोजन कर सकते हैं जैसे:
if let dragon = try? summonDefaultDragon()
या
guard let dragon = try? summonDefaultDragon() else { ... }
अंत में, आप यह तय कर सकते हैं कि आप जानते हैं कि त्रुटि वास्तव में नहीं होगी (उदाहरण के लिए क्योंकि आपने पहले से जाँच की है और आवश्यक शर्तें हैं) और try!
कीवर्ड का उपयोग करें :
let dragon = try! summonDefaultDragon()
यदि फ़ंक्शन वास्तव में एक त्रुटि फेंकता है, तो आपको अपने आवेदन में एक रनटाइम त्रुटि मिलेगी और एप्लिकेशन समाप्त हो जाएगा।
त्रुटि फेंकने के लिए आप इस तरह से कीवर्ड का उपयोग करें
throw DragonError.dragonIsMissing
आप ErrorType
प्रोटोकॉल के अनुरूप कुछ भी फेंक सकते हैं । शुरुआत के NSError
लिए इस प्रोटोकॉल के अनुरूप है, लेकिन आप शायद एनम-आधारित के साथ जाना चाहते हैं ErrorType
जो आपको कई संबंधित त्रुटियों को समूह करने में सक्षम बनाता है, संभवतः डेटा के अतिरिक्त टुकड़ों के साथ, जैसे कि
enum DragonError: ErrorType {
case dragonIsMissing
case notEnoughMana(requiredMana: Int)
...
}
नई स्विफ्ट 2 और 3 त्रुटि तंत्र और जावा / सी # / सी + + शैली अपवादों के बीच मुख्य अंतर निम्नानुसार हैं:
do-catch
+ try
+ defer
बनाम पारंपरिक try-catch-finally
सिंटैक्स।do-catch
ब्लॉक किसी भी NSException को नहीं पकड़ेगा, और इसके विपरीत, इसके लिए आपको ObjC का उपयोग करना होगा।NSError
विधि की परंपराओं के साथ संगत हैं false
( या Bool
वापस लौटने वाले कार्यों के लिए) या nil
( AnyObject
लौटने वाले कार्यों के लिए) और NSErrorPointer
त्रुटि विवरण के साथ गुजर रहे हैं।त्रुटि को कम करने के लिए एक अतिरिक्त सिंटैटिक-चीनी के रूप में, दो और अवधारणाएं हैं
defer
कीवर्ड का उपयोग करके ) जो आपको जावा / सी # / आदि में अंत में ब्लॉक के समान प्रभाव प्राप्त करने देती हैंguard
कीवर्ड का उपयोग करते हुए ) जो आपको सामान्य त्रुटि की जाँच / सिग्नलिंग कोड की तुलना में कम / यदि कोड लिखते हैं।रनटाइम त्रुटियाँ:
जैसा कि लिएंड्रो रनटाइम त्रुटियों से निपटने के लिए सुझाव देते हैं (जैसे नेटवर्क कनेक्टिविटी की समस्याएं, डेटा पार्स करना, फ़ाइल खोलना, आदि) आपको NSError
ओब्जेक में जैसे आप का उपयोग करना चाहिए , क्योंकि फाउंडेशन, ऐपिट, यूआईकिट, आदि ने इस तरह से अपनी त्रुटियों की रिपोर्ट की है। तो यह भाषा की चीज से ज्यादा ढांचा है।
एक और लगातार पैटर्न जो प्रयोग किया जा रहा है, वो है AFNetworking की तरह विभाजक सफलता / विफलता ब्लॉक:
var sessionManager = AFHTTPSessionManager(baseURL: NSURL(string: "yavin4.yavin.planets"))
sessionManager.HEAD("/api/destoryDeathStar", parameters: xwingSquad,
success: { (NSURLSessionDataTask) -> Void in
println("Success")
},
failure:{ (NSURLSessionDataTask, NSError) -> Void in
println("Failure")
})
अभी भी विफलता ब्लॉक को अक्सर NSError
उदाहरण मिलता है, त्रुटि का वर्णन करता है।
प्रोग्रामर त्रुटियाँ:
प्रोग्रामर त्रुटियों के लिए (जैसे सरणी तत्व की सीमा तक पहुंच से बाहर, एक फ़ंक्शन कॉल के लिए पारित अवैध तर्क, आदि) आपने ओबजैक में अपवादों का उपयोग किया। स्विफ्ट भाषा को अपवादों (जैसे throw
, catch
कीवर्ड आदि) के लिए कोई भाषा समर्थन नहीं लगता है । हालाँकि, जैसा कि प्रलेखन से पता चलता है कि यह ओबीजीसी के समान रनटाइम पर चल रहा है, और इसलिए आप अभी भी NSExceptions
इस तरह फेंकने में सक्षम हैं :
NSException(name: "SomeName", reason: "SomeReason", userInfo: nil).raise()
आप बस उन्हें शुद्ध स्विफ्ट में नहीं पकड़ सकते हैं, हालांकि आप ओबीजीसी कोड में अपवादों को पकड़ने का विकल्प चुन सकते हैं।
सवाल यह है कि क्या आपको प्रोग्रामर त्रुटियों के लिए अपवादों को फेंकना चाहिए, या जैसा कि भाषा गाइड में Apple सुझाव देता है, का उपयोग करें।
fatalError(...)
साथ ही एक ही है।
9 जून 2015 को अपडेट करें - बहुत महत्वपूर्ण
स्विफ्ट 2.0 के साथ आता है try
, throw
और catch
खोजशब्दों और सबसे रोमांचक है:
स्विफ्ट स्वचालित रूप से ऑब्जेक्टिव-सी तरीकों का अनुवाद करता है जो स्विफ्ट की मूल त्रुटि हैंडलिंग कार्यक्षमता के अनुसार त्रुटि फेंकने वाले तरीकों में त्रुटियां पैदा करता है।
नोट: वे विधियाँ जो त्रुटियों का उपभोग करती हैं, जैसे प्रतिनिधि विधियाँ या विधियाँ जो NSError ऑब्जेक्ट तर्क के साथ पूरा हैंडलर लेती हैं, स्विफ्ट द्वारा आयात किए जाने पर फेंकने वाली विधियाँ नहीं बनती हैं।
इसके अंश: Apple Inc. "कोको और ऑब्जेक्टिव-सी (स्विफ्ट 2 प्रीलेयरेज) के साथ स्विफ्ट का उपयोग करना।" iBooks।
उदाहरण: (पुस्तक से)
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *URL = [NSURL fileURLWithPath:@"/path/to/file"];
NSError *error = nil;
BOOL success = [fileManager removeItemAtURL:URL error:&error];
if (!success && error){
NSLog(@"Error: %@", error.domain);
}
स्विफ्ट में बराबर होगा:
let fileManager = NSFileManager.defaultManager()
let URL = NSURL.fileURLWithPath("path/to/file")
do {
try fileManager.removeItemAtURL(URL)
} catch let error as NSError {
print ("Error: \(error.domain)")
}
त्रुटि फेंकना:
*errorPtr = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCannotOpenFile userInfo: nil]
स्वचालित रूप से फोन करने वाले को प्रचारित किया जाएगा:
throw NSError(domain: NSURLErrorDomain, code: NSURLErrorCannotOpenFile, userInfo: nil)
Apple किताबों से, द स्विफ्ट प्रोग्रामिंग लैंग्वेज से ऐसा लगता है कि त्रुटियों को एनम का उपयोग करना चाहिए।
यहाँ पुस्तक से एक उदाहरण है।
enum ServerResponse {
case Result(String, String)
case Error(String)
}
let success = ServerResponse.Result("6:00 am", "8:09 pm")
let failure = ServerResponse.Error("Out of cheese.")
switch success {
case let .Result(sunrise, sunset):
let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)."
case let .Error(error):
let serverResponse = "Failure... \(error)"
}
से: Apple Inc. "स्विफ्ट प्रोग्रामिंग लैंग्वेज।" iBooks। https://itun.es/br/jEUH0.l
अपडेट करें
Apple समाचार पुस्तकों से, "स्विफ्ट विद कोको और ऑब्जेक्टिव-सी का उपयोग करना"। रनटाइम अपवाद स्विफ्ट भाषाओं का उपयोग नहीं करते हैं, इसलिए आपके पास ट्राइ-कैच नहीं है। इसके बजाय आप ऑप्शनल चेनिंग का उपयोग करें ।
यहाँ पुस्तक से एक खिंचाव है:
उदाहरण के लिए, नीचे दी गई कोड सूची में, पहली और दूसरी पंक्तियों को निष्पादित नहीं किया जाता है क्योंकि लंबाई संपत्ति और विशेषताएंडइंडेक्स: विधि एनएसडीट ऑब्जेक्ट पर मौजूद नहीं है। MyLength निरंतर एक वैकल्पिक Int होने का अनुमान है, और शून्य पर सेट है। आप उस पद्धति के परिणाम को सशर्त रूप से अनचेक करने के लिए एक if-let स्टेटमेंट का उपयोग कर सकते हैं, जो ऑब्जेक्ट पर प्रतिक्रिया नहीं दे सकता है, जैसा कि लाइन तीन पर दिखाया गया है
let myLength = myObject.length?
let myChar = myObject.characterAtIndex?(5)
if let fifthCharacter = myObject.characterAtIndex(5) {
println("Found \(fifthCharacter) at index 5")
}
इसके अंश: Apple Inc. "कोको और उद्देश्य-सी के साथ स्विफ्ट का उपयोग करना।" iBooks। https://itun.es/br/1u3-0.l
और किताबें आपको उद्देश्य-सी (NSError Object) से कोको त्रुटि पैटर्न का उपयोग करने के लिए प्रोत्साहित करती हैं
स्विफ्ट में रिपोर्ट करने में त्रुटि उसी पैटर्न का अनुसरण करती है जो वैकल्पिक रिटर्न मानों की पेशकश के अतिरिक्त लाभ के साथ ऑब्जेक्टिव-सी में होती है। सरलतम मामले में, आप यह इंगित करने के लिए फ़ंक्शन से बूल मान लौटाते हैं कि यह सफल हुआ या नहीं। जब आपको त्रुटि के कारण की रिपोर्ट करने की आवश्यकता होती है, तो आप NSErrorPerter प्रकार के NSError आउट पैरामीटर फ़ंक्शन को जोड़ सकते हैं। यह प्रकार मोटे तौर पर ऑब्जेक्टिव-सी के NSError ** के बराबर है, अतिरिक्त मेमोरी सुरक्षा और वैकल्पिक टाइपिंग के साथ। आप NSErrorPointer ऑब्जेक्ट के रूप में वैकल्पिक NSError प्रकार के संदर्भ में पास करने के लिए उपसर्ग और ऑपरेटर का उपयोग कर सकते हैं, जैसा कि नीचे दी गई कोड सूची में दिखाया गया है।
var writeError : NSError?
let written = myString.writeToFile(path, atomically: false,
encoding: NSUTF8StringEncoding,
error: &writeError)
if !written {
if let error = writeError {
println("write failure: \(error.localizedDescription)")
}
}
इसके अंश: Apple Inc. "कोको और उद्देश्य-सी के साथ स्विफ्ट का उपयोग करना।" iBooks। https://itun.es/br/1u3-0.l
ऑब्जेक्टिव-सी के दृष्टिकोण के समान स्विफ्ट में कोई अपवाद नहीं हैं।
विकास में, आप assert
किसी भी त्रुटि को पकड़ने के लिए उपयोग कर सकते हैं, जो उत्पादन में जाने से पहले निश्चित हो सकती है, और इसे ठीक करने की आवश्यकता है।
क्लासिक NSError
दृष्टिकोण को बदल नहीं दिया जाता है, आप एक भेजते हैं NSErrorPointer
, जो आबादी में हो जाता है।
संक्षिप्त उदाहरण:
var error: NSError?
var contents = NSFileManager.defaultManager().contentsOfDirectoryAtPath("/Users/leandros", error: &error)
if let error = error {
println("An error occurred \(error)")
} else {
println("Contents: \(contents)")
}
f();g();
बन जाए f(&err);if(err) return;g(&err);if(err) return;
, फिर वह बस बन जाएf(nil);g(nil);hopeToGetHereAlive();
अनुशंसित 'स्विफ्ट वे' है:
func write(path: String)(#error: NSErrorPointer) -> Bool { // Useful to curry error parameter for retrying (see below)!
return "Hello!".writeToFile(path, atomically: false, encoding: NSUTF8StringEncoding, error: error)
}
var writeError: NSError?
let written = write("~/Error1")(error: &writeError)
if !written {
println("write failure 1: \(writeError!.localizedDescription)")
// assert(false) // Terminate program
}
हालाँकि, मैं कोशिश करना / पकड़ना पसंद करता हूं क्योंकि मुझे इसका पालन करना आसान लगता है क्योंकि यह अंत में एक अलग ब्लॉक में त्रुटि हैंडलिंग को स्थानांतरित करता है, इस व्यवस्था को कभी-कभी "गोल्डन पाथ" कहा जाता है। भाग्यशाली आप इसे बंद करने के साथ कर सकते हैं:
TryBool {
write("~/Error2")(error: $0) // The code to try
}.catch {
println("write failure 2: \($0!.localizedDescription)") // Report failure
// assert(false) // Terminate program
}
इसके अलावा रिट्रीट सुविधा को जोड़ना आसान है:
TryBool {
write("~/Error3")(error: $0) // The code to try
}.retry {
println("write failure 3 on try \($1 + 1): \($0!.localizedDescription)")
return write("~/Error3r") // The code to retry
}.catch {
println("write failure 3 catch: \($0!.localizedDescription)") // Report failure
// assert(false) // Terminate program
}
TryBool के लिए लिस्टिंग है:
class TryBool {
typealias Tryee = NSErrorPointer -> Bool
typealias Catchee = NSError? -> ()
typealias Retryee = (NSError?, UInt) -> Tryee
private var tryee: Tryee
private var retries: UInt = 0
private var retryee: Retryee?
init(tryee: Tryee) {
self.tryee = tryee
}
func retry(retries: UInt, retryee: Retryee) -> Self {
self.retries = retries
self.retryee = retryee
return self
}
func retry(retryee: Retryee) -> Self {
return self.retry(1, retryee)
}
func retry(retries: UInt) -> Self {
// For some reason you can't write the body as "return retry(1, nil)", the compiler doesn't like the nil
self.retries = retries
retryee = nil
return self
}
func retry() -> Self {
return retry(1)
}
func catch(catchee: Catchee) {
var error: NSError?
for numRetries in 0...retries { // First try is retry 0
error = nil
let result = tryee(&error)
if result {
return
} else if numRetries != retries {
if let r = retryee {
tryee = r(error, numRetries)
}
}
}
catchee(error)
}
}
आप बूल मान के बजाय वैकल्पिक लौटे मान के परीक्षण के लिए एक समान वर्ग लिख सकते हैं:
class TryOptional<T> {
typealias Tryee = NSErrorPointer -> T?
typealias Catchee = NSError? -> T
typealias Retryee = (NSError?, UInt) -> Tryee
private var tryee: Tryee
private var retries: UInt = 0
private var retryee: Retryee?
init(tryee: Tryee) {
self.tryee = tryee
}
func retry(retries: UInt, retryee: Retryee) -> Self {
self.retries = retries
self.retryee = retryee
return self
}
func retry(retryee: Retryee) -> Self {
return retry(1, retryee)
}
func retry(retries: UInt) -> Self {
// For some reason you can't write the body as "return retry(1, nil)", the compiler doesn't like the nil
self.retries = retries
retryee = nil
return self
}
func retry() -> Self {
return retry(1)
}
func catch(catchee: Catchee) -> T {
var error: NSError?
for numRetries in 0...retries {
error = nil
let result = tryee(&error)
if let r = result {
return r
} else if numRetries != retries {
if let r = retryee {
tryee = r(error, numRetries)
}
}
}
return catchee(error)
}
}
TryOptional संस्करण एक गैर-वैकल्पिक रिटर्न प्रकार लागू करता है जो बाद की प्रोग्रामिंग को आसान बनाता है, जैसे 'स्विफ्ट वे:
struct FailableInitializer {
init?(_ id: Int, error: NSErrorPointer) {
// Always fails in example
if error != nil {
error.memory = NSError(domain: "", code: id, userInfo: [:])
}
return nil
}
private init() {
// Empty in example
}
static let fallback = FailableInitializer()
}
func failableInitializer(id: Int)(#error: NSErrorPointer) -> FailableInitializer? { // Curry for retry
return FailableInitializer(id, error: error)
}
var failError: NSError?
var failure1Temp = failableInitializer(1)(error: &failError)
if failure1Temp == nil {
println("failableInitializer failure code: \(failError!.code)")
failure1Temp = FailableInitializer.fallback
}
let failure1 = failure1Temp! // Unwrap
TryOptional का उपयोग करना:
let failure2 = TryOptional {
failableInitializer(2)(error: $0)
}.catch {
println("failableInitializer failure code: \($0!.code)")
return FailableInitializer.fallback
}
let failure3 = TryOptional {
failableInitializer(3)(error: $0)
}.retry {
println("failableInitializer failure, on try \($1 + 1), code: \($0!.code)")
return failableInitializer(31)
}.catch {
println("failableInitializer failure code: \($0!.code)")
return FailableInitializer.fallback
}
नोट ऑटो-अलॉटिंग।
संपादित करें: हालांकि यह उत्तर काम करता है, यह स्विफ्ट में किए गए ऑब्जेक्टिव-सी से थोड़ा अधिक है। इसे स्विफ्ट 2.0 में बदलाव करके अप्रचलित कर दिया गया है। ऊपर गिलेहार्म टोरेस कास्त्रो का जवाब स्विफ्ट में त्रुटियों से निपटने के पसंदीदा तरीके से बहुत अच्छा परिचय है। VOS
यह थोड़ा समझ में आया, लेकिन मुझे लगता है कि मैंने इसे मार दिया है। हालांकि यह बदसूरत लगता है। ऑब्जेक्टिव-सी संस्करण पर एक पतली त्वचा से ज्यादा कुछ नहीं।
NSError पैरामीटर के साथ एक फ़ंक्शन कॉल करना ...
var fooError : NSError ? = nil
let someObject = foo(aParam, error:&fooError)
// Check something was returned and look for an error if it wasn't.
if !someObject {
if let error = fooError {
// Handle error
NSLog("This happened: \(error.localizedDescription)")
}
} else {
// Handle success
}`
त्रुटि पैरामीटर लेने वाले फ़ंक्शन को लिखना ...
func foo(param:ParamObject, error: NSErrorPointer) -> SomeObject {
// Do stuff...
if somethingBadHasHappened {
if error {
error.memory = NSError(domain: domain, code: code, userInfo: [:])
}
return nil
}
// Do more stuff...
}
उद्देश्य सी के आसपास बुनियादी आवरण जो आपको पकड़ने की सुविधा प्रदान करता है। https://github.com/williamFalcon/SwiftTryCatch
जैसे उपयोग करें:
SwiftTryCatch.try({ () -> Void in
//try something
}, catch: { (error) -> Void in
//handle error
}, finally: { () -> Void in
//close resources
})
यह तेजी से 2.0 के लिए एक अद्यतन जवाब है। मैं java की तरह आगे की सुविधा संपन्न एरर हैंडलिंग मॉडल देख रहा हूँ। अंत में, उन्होंने खुशखबरी की घोषणा की। यहाँ
हैंडलिंग मॉडल में त्रुटि: स्विफ्ट 2.0 में नया एरर हैंडलिंग मॉडल सहज रूप से परिचित , कोशिश, फेंक और कीवर्ड को पकड़ने के साथ स्वाभाविक लगेगा । सबसे अच्छा, यह Apple SDKs और NSError के साथ पूरी तरह से काम करने के लिए डिज़ाइन किया गया था। वास्तव में, NSError एक Swift के ErrorType के अनुरूप है। आप निश्चित रूप से इसके बारे में अधिक सुनने के लिए स्विफ्ट में व्हाट्स न्यू पर WWDC सत्र देखना चाहते हैं।
जैसे:
func loadData() throws { }
func test() {
do {
try loadData()
} catch {
print(error)
}}
के रूप में गुइलहर्मे टोरेस कास्त्रो ने कहा, स्विफ्ट 2.0 में, try
, catch
, do
प्रोग्रामिंग में इस्तेमाल किया जा सकता।
उदाहरण के लिए, कोरडाटा में डेटा विधि, &error
एक पैरामीटर के रूप में डालने के बजाय managedContext.executeFetchRequest(fetchRequest, error: &error)
, अब हमें केवल उपयोग की आवश्यकता है managedContext.executeFetchRequest(fetchRequest)
और फिर त्रुटि को संभालना होगा try
, catch
( Apple दस्तावेज़ लिंक )
do {
let fetchedResults = try managedContext.executeFetchRequest(fetchRequest) as? [NSManagedObject]
if let results = fetchedResults{
people = results
}
} catch {
print("Could not fetch")
}
यदि आप पहले से ही xcode7 बीटा डाउनलोड कर चुके हैं। दस्तावेज़ीकरण और एपीआई संदर्भ में फेंकने वाली त्रुटियों को खोजने की कोशिश करें और पहला प्रदर्शन परिणाम चुनें, यह एक मूल विचार देता है कि इस वाक्यविन्यास वाक्य के लिए क्या किया जा सकता है। हालाँकि, पूरी तरह से प्रलेखन अभी तक कई एपीआई के लिए पोस्ट नहीं है।
अधिक फैंसी त्रुटि हैंडलिंग तकनीकों में पाया जा सकता है
व्हाट्स न्यू इन स्विफ्ट (2015 सत्र 106 28 मीटर 30)
त्रुटि हैंडलिंग स्विफ्ट 2.0 की एक नई विशेषता है। यह का उपयोग करता है try
, throw
और catch
कीवर्ड।
आधिकारिक ऐपल स्विफ्ट ब्लॉग पर ऐप्पल स्विफ्ट 2.0 की घोषणा देखें
अपवाद को संभालने के लिए अच्छा और सरल काम: TryCatchFinally-Swift
कुछ अन्य लोगों की तरह यह उद्देश्य C अपवाद सुविधाओं के आसपास लपेटता है।
इसे इस तरह उपयोग करें:
try {
println(" try")
}.catch { e in
println(" catch")
}.finally {
println(" finally")
}
स्विफ्ट 2 के साथ शुरू करना, जैसा कि दूसरों ने पहले ही उल्लेख किया है, त्रुटि हैंडलिंग सबसे अच्छी तरह से do / try / catch और ErrorType नंबरों के उपयोग के माध्यम से पूरा किया गया है। यह सिंक्रोनस तरीकों के लिए काफी अच्छी तरह से काम करता है, लेकिन अतुल्यकालिक त्रुटि से निपटने के लिए थोड़ी चतुराई की आवश्यकता होती है।
इस लेख में इस समस्या के लिए एक महान दृष्टिकोण है:
https://jeremywsherman.com/blog/2015/06/17/using-swift-throws-with-completion-callbacks/
संक्षेप में:
// create a typealias used in completion blocks, for cleaner code
typealias LoadDataResult = () throws -> NSData
// notice the reference to the typealias in the completionHandler
func loadData(someID: String, completionHandler: LoadDataResult -> Void)
{
completionHandler()
}
फिर, उपरोक्त विधि के लिए कॉल इस प्रकार होगा:
self.loadData("someString",
completionHandler:
{ result: LoadDataResult in
do
{
let data = try result()
// success - go ahead and work with the data
}
catch
{
// failure - look at the error code and handle accordingly
}
})
यह एक अलग क्लीनर होने की तुलना में थोड़ा साफ लगता है। हैन्डलर कॉलबैक को अतुल्यकालिक फ़ंक्शन में पारित किया गया था, जो कि स्विफ्ट 2 से पहले कैसे संभाला जाएगा।
मैंने जो देखा है, वह यह है कि डिवाइस की प्रकृति के कारण आप उपयोगकर्ता पर संदेश भेजने में गुप्त त्रुटि का एक गुच्छा फेंकना नहीं चाहते हैं। यही कारण है कि अधिकांश फ़ंक्शन वैकल्पिक मान लौटाते हैं तो आप वैकल्पिक को अनदेखा करने के लिए कोड करते हैं। यदि कोई फ़ंक्शन वापस आता है जिसका अर्थ है कि यह विफल हो गया है तो आप एक संदेश या जो कुछ भी कर सकते हैं।