Swift में एसिंक्रोनस प्रोग्रामिंग का परिचय
Swift (iOS/macOS) पर आधुनिक मोबाइल और डेस्कटॉप एप्लिकेशन को उपयोगकर्ता इंटरफ़ेस को ब्लॉक किए बिना लंबी अवधि के संचालन — नेटवर्क से डेटा लोड करना, फ़ाइलों के साथ काम करना, इमेज प्रोसेसिंग — करने की आवश्यकता होती है। हाल तक, डेवलपर्स क्लोजर (completion handlers) और Grand Central Dispatch (GCD) का उपयोग करते थे, जिससे तथाकथित "कॉलबैक नरक" होता था और कोड पढ़ना मुश्किल हो जाता था। Swift 5.5 के आगमन के साथ, Apple ने एसिंक्रोनस प्रोग्रामिंग का एक मौलिक रूप से नया मॉडल पेश किया, जो कीवर्ड async और await, साथ ही एक्टर और Task संरचनाओं पर आधारित है। इस गाइड में, हम व्यावहारिक उदाहरणों के साथ सभी प्रमुख अवधारणाओं को समझेंगे।
1. Swift में async/await की मूल बातें
कीवर्ड async इंगित करता है कि कोई फ़ंक्शन या मेथड एसिंक्रोनस ऑपरेशन के परिणाम की प्रतीक्षा करने के लिए अपने निष्पादन को रोक सकता है। ऐसे फ़ंक्शन को कॉल करने पर await शब्द का उपयोग किया जाता है। यह एसिंक्रोनस कोड को सिंक्रोनस कोड की तरह ही रैखिक रूप से लिखने की अनुमति देता है।
// एसिंक्रोनस फ़ंक्शन घोषित करनाfunc fetchUserData(from url: URL) async throws -> Data { let (data, _) = try await URLSession.shared.data(from: url) return data}
// इसे टास्क के संदर्भ में उपयोग करनाTask { do { let url = URL(string: "https://api.example.com/user")! let userData = try await fetchUserData(from: url) print("डेटा प्राप्त हुआ: \\(userData.count) बाइट्स") } catch { print("लोड करने में त्रुटि: \\(error.localizedDescription)") }}ध्यान दें: await कॉल वर्तमान टास्क को रोकता है, लेकिन थ्रेड को ब्लॉक नहीं करता है। जब परिणाम तैयार होता है तो सिस्टम स्वयं संदर्भ बदलता है, जो कोड को कुशल और सुरक्षित बनाता है।
2. एक्टर (Actors) — स्थिति के साथ सुरक्षित कार्य
एसिंक्रोनसिटी डेटा रेस (data race) की समस्या जोड़ती है। इसे हल करने के लिए Swift में एक्टर पेश किए गए हैं। एक्टर एक रेफरेंस टाइप है जो अपनी स्थिति को अलग करता है और गारंटी देता है कि किसी भी समय केवल एक टास्क ही इसके परिवर्तनीय गुणों तक पहुँच सकता है।
actor Counter { private var value = 0 func increment() { value += 1 } func getValue() -> Int { return value }}
// एक्टर का उपयोगlet counter = Counter()
Task { await counter.increment() let currentValue = await counter.getValue() print("वर्तमान मान: \\(currentValue)")}कीवर्ड actor स्वचालित रूप से सभी मेथड और गुणों (अपरिवर्तनीय को छोड़कर) को बाहरी पहुँच के लिए एसिंक्रोनस बना देता है। यह मैन्युअल लॉक प्रबंधन (NSLock, DispatchSemaphore) की विशेषता वाले ब्लॉक और डेडलॉक से बचने में मदद करता है।
3. TaskGroup और टास्क का समानांतर निष्पादन
जब कई स्वतंत्र एसिंक्रोनस ऑपरेशन को समानांतर में निष्पादित करने की आवश्यकता होती है, तो TaskGroup का उपयोग करें। यह एक संरचना है जो चाइल्ड टास्क शुरू करने और उनके परिणाम एकत्र करने की अनुमति देती है।
func fetchMultipleUsers(ids: [Int]) async throws -> [User] { try await withThrowingTaskGroup(of: User.self) { group in var users: [User] = [] for id in ids { group.addTask { let url = URL(string: "https://api.example.com/users/\\(id)")! let data = try await URLSession.shared.data(from: url) return try JSONDecoder().decode(User.self, from: data.0) } } for try await user in group { users.append(user) } return users }}
// उपयोगTask { let users = try? await fetchMultipleUsers(ids: [1, 2, 3, 4, 5]) print("उपयोगकर्ता लोड हुए: \\(users?.count ?? 0)")}मेथड withThrowi