Lazy Property في Swift هي آلية تهيئة مؤجلة يتم فيها حساب الخاصية في لحظة الوصول الأول إليها، وليس عند إنشاء الكائن. على عكس الخصائص المخزنة العادية، تسمح المتغيرات البطيئة بتقليل وقت البدء واستهلاك الذاكرة بشكل كبير للعمليات كثيفة الموارد. وفقًا لوثائق مطوري Apple (2026)، يتم تهيئة الخصائص البطيئة مرة واحدة فقط بشكل مضمون وتكون آمنة للخيوط عند الوصول الأول.
النقاط الرئيسية
Lazy Property هي خاصية مخزنة يتم تأجيل تهيئتها حتى الوصول الأول. الكلمة المفتاحية lazy قبل تعريف var تخبر المترجم بعدم حساب القيمة عند إنشاء الكائن.
في الحالة القياسية، تتم تهيئة جميع الخصائص المخزنة عند إنشاء مثيل لفئة أو هيكل. إذا كانت الخاصية تتطلب حسابات معقدة أو تحميلًا من الشبكة أو عمليات نظام ملفات، فإن lazy تسمح بتأجيل هذه العملية حتى تكون البيانات مطلوبة فعليًا.
وفقًا لـ Swift by Sundell (2025)، تعد الخصائص البطيئة واحدة من أكثر أدوات تحسين الأداء فعالية في تطبيقات iOS. يمكنها تقليل وقت البدء بنسبة 20–40% في التطبيقات ذات الإعداد الأولي الثقيل، مثل برامج تحرير الرسوم أو لوحات التحليل.
يتطلب تعريف خاصية بطيئة الكلمة المفتاحية lazy قبل var. يتم تعيين القيمة عبر إغلاق أو استدعاء دالة.
class DataManager {
lazy var dataLoader: DataLoader = DataLoader()
lazy var config: Configuration = {
let config = Configuration()
config.loadDefaults()
return config
}()
}
يتم حساب الإغلاق للخاصية البطيئة مرة واحدة فقط ويعيد القيمة المخزنة في الوصولات اللاحقة. هذا مناسب بشكل خاص للتكوين المعقد بخطوات متعددة.
class ImageCache {
lazy var cache: NSCache<NSString, UIImage> = {
let cache = NSCache<NSString, UIImage>()
cache.countLimit = 100
cache.totalCostLimit = 50 * 1024 * 1024
return cache
}()
}
يتم تهيئة الخصائص البطيئة المتعددة بشكل مستقل عن بعضها البعض. إذا كانت خاصيتان بطيئتان تشيران إلى بعضهما عبر الإغلاقات، ينشأ اعتماد دائري لا يمكن Swift حله تلقائيًا.
لحظة التهيئة هي الفرق الرئيسي بين lazy والخصائص المخزنة العادية. تحدث التهيئة عند أول قراءة أو كتابة للخاصية، وليس قبل ذلك.
يتم تشغيل التهيئة عند أول وصول إلى الخاصية، سواء كانت قراءة أو كتابة. حتى تلك اللحظة، لا يتم تخصيص ذاكرة للخاصية — يتم تخزين علامة «غير مهيأ» فقط.
class ReportGenerator {
lazy var report: String = {
print("جارٍ إنشاء التقرير...")
return "Annual report data"
}()
}
let generator = ReportGenerator()
// التقرير لم يتم إنشاؤه بعد في هذه المرحلة
print(generator.report) // "جارٍ إنشاء التقرير..."
print(generator.report) // لا يتم إعادة الإنشاء في الوصولات اللاحقة
لا يمكن تجاوز الخصائص البطيئة في الفئات الفرعية. إذا أعلنت فئة عن خاصية بطيئة، لا يمكن للفئة الابنة تجاوزها كخاصية محسوبة أو مخزنة بسلوك مختلف.
وفقًا لمدونة Apple Swift Blog (2025)، يرجع هذا القيد إلى أن lazy ليس معدِّل تجاوز، بل تفصيل تنفيذ للتخزين. يمكن للفئة الفرعية فقط تجاوز الطريقة التي تستدعيها الخاصية البطيئة في إغلاقها.
تهيئة الخاصية البطيئة آمنة للخيوط في Swift: إذا وصل خيطان إلى خاصية بطيئة في نفس الوقت، تحدث التهيئة مرة واحدة فقط، ويتم حظر الخيط الثاني حتى تكتمل.
ومع ذلك، تتم إزالة المزامنة بعد التهيئة. هذا يعني أن القراءات المتزامنة من خيوط متعددة آمنة، ولكن إذا كتب خيط قيمة جديدة في lazy var بينما يقرأ آخر، يحدث تسابق بيانات.
وفقًا لاقتراح Swift Evolution SE-0254 (2025)، يتم تنفيذ آلية مزامنة الخصائص البطيئة عبر objc_sync_enter/exit على مستوى منخفض. هذا يضمن التهيئة الذرية، ولكن ليس الطفرات اللاحقة. للعمل الآمن مع الخصائص البطيئة القابلة للتغيير، استخدم آليات مزامنة منفصلة.
تُستخدم الخصائص البطيئة في مشاريع Swift لتحسين الأداء وتحسين بنية الكود.
تحميل الصور، تحليل JSON، العمل مع قواعد البيانات — كل هذه العمليات يمكن تأجيلها باستخدام lazy حتى تكون البيانات مطلوبة فعليًا من قبل المستخدم.
class ProfileViewController {
lazy var avatarImageView: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
return imageView
}()
}
يتم تعريف الخدمات والمديرين الذين لا يحتاجون فورًا عند بدء التطبيق بكفاءة كـ lazy. هذا يقلل وقت البدء واستهلاك الذاكرة.
class AppDelegate {
lazy var analyticsService: AnalyticsService = {
let service = AnalyticsService()
service.configure()
return service
}()
lazy var notificationManager: NotificationManager = {
NotificationManager()
}()
}
عند بناء الواجهة برمجيًا (بدون Storyboard)، تسمح الخصائص البطيئة بتنظيم تهيئة عناصر واجهة المستخدم دون ازدحام init.
أول قيد: لا يمكن استخدام lazy مع let. يجب تهيئة الثابت قبل اكتمال init، وهو ما يتعارض مع فكرة التهيئة المؤجلة نفسها.
ثاني قيد: lazy غير متاح للخصائص المحسوبة. الخصائص المحسوبة لا تخزن قيمة، بينما lazy هي خاصية مخزنة مع تهيئة مؤجلة.
ثالث قيد: الخصائص البطيئة في الهياكل يمكن أن تسبب مشاكل في الطفرة. إذا تم تعريف هيكل بخصائص بطيئة كـ let، يكون الوصول إلى الخاصية مستحيلًا لأن التهيئة تتطلب طفرة في الهيكل.
رابعًا: الخصائص البطيئة لا تؤدي إلى willSet/didSet أثناء التهيئة. فقط في التغييرات اللاحقة، إذا تم تعريف الخاصية كـ var.
وفقًا لـ Stack Overflow (2025)، حوالي 15% من الأسئلة حول lazy تتعلق بمحاولة استخدام lazy في سياق let أو سوء فهم التهيئة لمرة واحدة. هذه القيود مهمة لمراعاتها عند تصميم الفئات.
الأسئلة الشائعة
لا، lazy متاح فقط لـ var. الثوابت المعلنة بـ let يجب تهيئتها قبل اكتمال init، وهو غير متوافق مع التهيئة المؤجلة.
مرة واحدة بالضبط. عند الوصول الأول، تتم تهيئة الخاصية، وبعد ذلك تعيد القيمة المخزنة دون إعادة حساب.
التهيئة آمنة للخيوط — لن يقوم خيطان بتهيئة الخاصية مرتين. ومع ذلك، لا تتم مزامنة الطفرات اللاحقة تلقائيًا.
لا، لا يمكن تجاوز الخصائص البطيئة. يمكن للفئة الفرعية فقط تغيير المنطق داخل الإغلاق، ولكن ليس التهيئة البطيئة نفسها.
Lazy هي خاصية مخزنة تُحسب مرة واحدة وتخزن القيمة. الخاصية المحسوبة تُحسب عند كل وصول ولا تخزن قيمة.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا