Sendable হলো একটি Swift প্রোটোকল যা থ্রেডের মধ্যে স্থানান্তরের জন্য নিরাপদ ধরনগুলি চিহ্নিত করে। কনকারেন্সি (actor, async/await, Task) নিয়ে কাজ করার সময়, Swift কম্পাইলার প্রয়োজন করে যে বিচ্ছিন্ন কনটেক্সটের মধ্যে স্থানান্তরিত সমস্ত ডেটা Sendable-এর সাথে সঙ্গতিপূর্ণ হতে হবে। এটি অসুরক্ষিত ধরনগুলির আকস্মিক স্থানান্তর প্রতিরোধ করে যা ডেটা রেসের কারণ হতে পারে। প্রোটোকলটি একটি চুক্তি হিসেবে কাজ করে: Sendable-এর সাথে সঙ্গতিপূর্ণ একটি ধরন অভ্যন্তরীণ অসম syncronized অবস্থার অনুপস্থিতি নিশ্চিত করে। WWDC 2021 অনুসারে, একটি নিরাপদ মাল্টিথ্রেডেড আর্কিটেকচার ডিজাইন করার সময় Sendable প্রোটোকল একটি বাধ্যতামূলক উপাদান।
মূল পয়েন্ট
Sendable হলো Swift স্ট্যান্ডার্ড লাইব্রেরির (SE-0302) একটি প্রোটোকল যা আইসোলেশন ডোমেনের মধ্যে স্থানান্তরের জন্য নিরাপদ ধরনগুলি চিহ্নিত করে। আইসোলেশন ডোমেন বলতে actor, Task বা @MainActor কনটেক্সট বোঝায়। Sendable-এ কোনো প্রয়োজনীয়তা নেই — এটি একটি নিরাপত্তা মার্কার হিসেবে কাজ করে।
Swift 5.5-এর আগে, ডেভেলপাররা DispatchQueue-এর মাধ্যমে থ্রেডের মধ্যে যেকোনো অবজেক্ট স্থানান্তর করতে পারতেন, এবং কম্পাইলার পরীক্ষা করত না যে এটি নিরাপদ কিনা। Sendable এই ফাঁক বন্ধ করে: এখন কম্পাইলার নিজেই ক্রস-থ্রেড স্থানান্তর ট্র্যাক করে এবং অসুরক্ষিত স্থানান্তর ব্লক করে। এটি কনকারেন্ট কোডকে চালানোর আগেই আরও নির্ভরযোগ্য করে তোলে।
struct UserProfile: Sendable {
let name: String
let age: Int
}
class NonSendableClass {
var counter: Int = 0
}
উদাহরণে, UserProfile থ্রেডের মধ্যে নিরাপদে স্থানান্তরিত হতে পারে কারণ এটি Sendable ধরনের ধ্রুবক বৈশিষ্ট্য সহ একটি স্ট্রাক্ট। NonSendableClass await-এর মাধ্যমে বা Task-এ স্থানান্তরের চেষ্টা করলে কম্পাইলেশন ত্রুটি সৃষ্টি করবে।
Sendable ধরনগুলি Swift-এ তিনটি শ্রেণিতে বিভক্ত: Sendable বৈশিষ্ট্য সহ ভ্যালু টাইপ, অপরিবর্তনীয় অবস্থা সহ ফাইনাল ক্লাস এবং @Sendable দিয়ে চিহ্নিত ফাংশন/ক্লোজার। কম্পাইলার ভ্যালু টাইপের জন্য স্বয়ংক্রিয়ভাবে Sendable সঙ্গতি অনুমান করে।
Struct, enum এবং tuple স্বয়ংক্রিয়ভাবে Sendable হয়ে যায় যদি তাদের সব বৈশিষ্ট্য এবং সম্পর্কিত মানও Sendable হয়। এটি একটি রক্ষণশীল পদ্ধতি: যদি অন্তত একটি বৈশিষ্ট্য Sendable-এর সাথে সঙ্গতিপূর্ণ না হয়, তাহলে পুরো ধরনটিকে নিরাপদ হিসাবে স্বীকৃত করা হবে না।
| ধরন | Sendable | শর্ত |
|---|---|---|
| Struct | হ্যাঁ (স্পষ্ট ঘোষণা ছাড়া) | সমস্ত বৈশিষ্ট্য Sendable |
| Enum | হ্যাঁ (স্পষ্ট ঘোষণা ছাড়া) | সমস্ত সম্পর্কিত মান Sendable |
| Final class | হ্যাঁ (স্পষ্ট ঘোষণা সহ) | সমস্ত let বৈশিষ্ট্য Sendable, কোনো var নেই |
| Non-final class | না | উত্তরাধিকারের কারণে Sendable হতে পারে না |
সমস্ত অন্তর্নির্মিত Swift ধরন — Int, String, Double, Bool, Optional, Array, Dictionary, Set — Sendable-এর সাথে সঙ্গতিপূর্ণ। এটি টাইপ কম্পোজিশনকে ডিফল্টভাবে নিরাপদ করে তোলে। ডেভেলপারকে শুধুমাত্র কাস্টম ক্লাসগুলির দিকে নজর দিতে হবে।
@unchecked Sendable হলো একটি মেকানিজম যা একটি ক্লাসকে কম্পাইলার চেক এড়িয়ে স্পষ্টভাবে নিজেকে Sendable ঘোষণা করতে দেয়। ডেভেলপার এই ধরনের ক্লাসের থ্রেড নিরাপত্তার দায়িত্ব নেয়। এটি Objective-C ব্রিজ এবং অপ্টিমাইজড স্ট্রাকচারের জন্য উপযোগী।
@unchecked Sendable ব্যবহার করা হয় যখন একটি ক্লাস অভ্যন্তরীণভাবে লক বা পারমাণবিক অপারেশনের মাধ্যমে নিরাপত্তা নিশ্চিত করে, কিন্তু কম্পাইলার স্থিরভাবে এটি যাচাই করতে পারে না। উদাহরণস্বরূপ, os_unfair_lock বা pthread_mutex_t সহ একটি ক্লাস — এর থ্রেড নিরাপত্তা কোড দ্বারা নিশ্চিত করা হয়, কিন্তু Swift এটি দেখতে পায় না।
final class AtomicCounter: @unchecked Sendable {
private var value: Int = 0
private let lock = NSLock()
func increment() {
lock.lock()
value += 1
lock.unlock()
}
}
@unchecked Sendable ব্যবহার করা উচিত সতর্কতার সাথে। এটি অন্যান্য ডেভেলপারদের জন্য একটি স্পষ্ট সংকেত: «আমি পরীক্ষা করেছি, এটি নিরাপদ।» বাস্তবায়নে ত্রুটি ধরা কঠিন রেসের কারণ হতে পারে। @unchecked ব্যবহারের আগে, নিশ্চিত করুন যে ধরনটি সত্যিই ভ্যালু টাইপ হিসাবে পুনরায় লেখা যাবে না।
Actor এবং Sendable একই মুদ্রার দুটি পিঠ। Actor তার অবস্থা বিচ্ছিন্ন করে, কিন্তু বাইরের বিশ্বের সাথে ডেটা বিনিময় করতে তাকে Sendable ধরন ফেরত দিতে হবে। যদি একটি actor পদ্ধতি নন-Sendable ধরন ফেরত দেয়, কম্পাইলার সতর্কতা বা ত্রুটি দেয়।
যখন একটি actor বাহ্যিক কোডে ডেটা পাঠায়, এই ডেটা বিচ্ছিন্নতা সীমানা অতিক্রম করে। Sendable নিশ্চিত করে যে প্রাপক actor-এর বাইরে এটি নিরাপদে ব্যবহার করতে পারে। Actor নিজেই বিচ্ছিন্ন থাকে — এর অভ্যন্তরীণ অবস্থা উন্মোচিত হয় না।
struct AccountSnapshot: Sendable {
let id: UUID
let balance: Double
let lastUpdated: Date
}
actor BankActor {
private var balance: Double = 0
func snapshot() async -> AccountSnapshot {
return AccountSnapshot(
id: UUID(),
balance: balance,
lastUpdated: Date()
)
}
}
AccountSnapshot হলো একটি Sendable স্ট্রাক্ট যা শুধুমাত্র Sendable ধরনের let বৈশিষ্ট্য ধারণ করে। এই পদ্ধতি actor থেকে ডেটা বের করার জন্য সর্বোত্তম অনুশীলন। অবস্থার স্ন্যাপশট মান দ্বারা স্থানান্তরিত হয়, এবং actor তার অবস্থার উপর নিয়ন্ত্রণ হারায় না।
@Sendable হলো ফাংশন এবং ক্লোজারের জন্য একটি অ্যাট্রিবিউট যা নিশ্চিত করে যে ক্লোজার পরিবর্তনযোগ্য আকারে নন-Sendable ডেটা ক্যাপচার করে না। যখন একটি ক্লোজার Task বা actor পদ্ধতিতে স্থানান্তরিত হয়, এটি অবশ্যই Sendable হতে হবে।
কম্পাইলার পরীক্ষা করে যে @Sendable ক্লোজার ক্লাসের পরিবর্তনযোগ্য রেফারেন্স ক্যাপচার করে না। Sendable ধরনের let বৈশিষ্ট্য ক্যাপচার করার অনুমতি রয়েছে। রেফারেন্স ধরনের var ভেরিয়েবল ক্যাপচার করলে ত্রুটি হবে কারণ ক্লোজারটি মিউটেশনের সাথে একসাথে নির্বাহিত হতে পারে।
func performAsync(operation: @Sendable () -> Void) {
Task {
await operation()
}
}
let constant = "Safe"
var counter = 0
// counter — var ক্যাপচার করলে counter পরিবর্তিত হয়, কম্পাইলেশন ত্রুটি
performAsync { // ❌ ক্যাপচার করা ভেরিয়েবলের পরিবর্তন
print(constant)
}
নিয়মটি সহজ: একটি @Sendable ক্লোজার শুধুমাত্র সেই ডেটা ক্যাপচার করতে পারে যা নিজে Sendable এবং বাইরে থেকে পরিবর্তন করা হবে না। ক্লাসের জন্য, দুর্বল রেফারেন্স weak self ক্যাপচার করার অনুমতি রয়েছে যদি ক্লাসটি Sendable হিসাবে চিহ্নিত না হয়। এটি ক্লাসিক রিটেইন সাইকেল এবং রেস কন্ডিশন প্রতিরোধ করে।
সচরাচর জিজ্ঞাসা
Sendable হলো একটি মার্কার যা কম্পাইলারকে বলে: «এই ধরনটি থ্রেডের মধ্যে নিরাপদে স্থানান্তরিত করা যেতে পারে।» স্ট্রাক্ট এবং ধ্রুবক সাধারণত ডিফল্টভাবে Sendable হয়, ক্লাস ততক্ষণ না যতক্ষণ স্পষ্টভাবে উল্লেখ করা হয়।
ভ্যালু টাইপ (struct, enum) Sendable বৈশিষ্ট্য সহ, অপরিবর্তনীয় অবস্থা সহ ফাইনাল ক্লাস এবং সমস্ত মৌলিক Swift ধরন: Int, String, Double, Bool, Array, Dictionary, Optional — স্বয়ংক্রিয়ভাবে Sendable-এর সাথে সঙ্গতিপূর্ণ।
@unchecked Sendable হলো কম্পাইলারের স্থির পরীক্ষা ছাড়াই একটি ক্লাসকে Sendable ঘোষণা করার একটি উপায়। ডেভেলপার নিজেই নিরাপত্তা নিশ্চিত করে, প্রায়শই লক বা পারমাণবিক অপারেশনের মাধ্যমে।
Actor তার অবস্থা বিচ্ছিন্ন করে, কিন্তু বাহ্যিক কোডে ডেটা ফেরত দেওয়ার সময়, এই ডেটা বিচ্ছিন্নতা সীমানা অতিক্রম করে। Sendable নিশ্চিত করে যে প্রাপক actor-এর বাইরে এই ডেটা ব্যবহার করার সময় রেসের সম্মুখীন হবে না।
একটি ফাইনাল ক্লাসে Sendable প্রোটোকল যুক্ত করুন, যার সব বৈশিষ্ট্য Sendable ধরনের ধ্রুবক। যদি ক্লাস লক ব্যবহার করে, @unchecked Sendable ব্যবহার করা যেতে পারে, তবে এর জন্য সতর্কতা প্রয়োজন।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন