Table of Contents
परिचय: क्यों कोर डेटा और NSFetchedResultsController पदार्थ
आधुनिक आईओएस विकास में, एक तरल पदार्थ पहुंचाने, उत्तरदायी उपयोगकर्ता इंटरफ़ेस अक्सर इस बात पर निर्भर करता है कि आपका ऐप उस समय के साथ डेटा को कैसे संभालता है। चाहे आप एक सामाजिक फ़ीड, एक कार्य प्रबंधक या एक सूची प्रणाली का निर्माण कर रहे हों, उपयोगकर्ताओं को प्रदर्शित डेटा शायद ही कभी स्थिर है। कोर डेटा — Apple की परिपक्व वस्तु ग्राफ और दृढ़ता ढांचा — (FRC) के साथ मिलकर गतिशील, बड़े पैमाने पर डेटासेट के प्रबंधन के लिए एक युद्ध-परीक्षित समाधान प्रदान करता है जबकि यूआई को बिना मैनुअल ओवरहेड के सिंक में रखता है।
यह लेख कोर डेटा का उपयोग करने के लिए गहन, व्यावहारिक गाइड प्रदान करता है, जिसमें सूचनाएं महत्वपूर्ण हैं। जब ऑब्जेक्ट्स को डाला जाता है, अद्यतन किया जाता है, या हटा दिया जाता है, तो संदर्भ इन परिवर्तनों को प्रसारित करता है, जो ठीक उसी तरह है जो ] आपके यूआई को सुसंगत रखने के लिए लाभ उठाता है।
आधिकारिक डेवलपर प्रलेखन के लिए, Apple के कोर डेटा फ्रेमवर्क संदर्भ को संदर्भित करें।
NSFetchedResultsController: The Bridge between Core Data and Your UI
] एक नियंत्रक वस्तु है जो कोर डेटा फीवर अनुरोध से लौटाए गए परिणामों को कुशलतापूर्वक प्रबंधित करने के लिए डिज़ाइन की गई है, खासकर जब अंतर्निहित डेटा को बदलने की उम्मीद है। यह प्रासंगिक प्रबंधित ऑब्जेक्ट संदर्भ की निगरानी करता है और स्वचालित रूप से इसके प्रतिनिधि प्रोटोकॉल के माध्यम से परिवर्तन की रिपोर्ट करता है।
मुख्य विशेषताएं
- ] स्वचालित परिवर्तन ट्रैकिंग: FRC संदर्भ अधिसूचनाओं को सुनता है और उन्हें संरचित प्रतिनिधि कॉलबैक (, ]]]], ]]]]]] में अनुवाद करता है।
- Built-in अनुभाग: ]] निर्दिष्ट करके, नियंत्रक समूह अनुभागों में परिणाम प्राप्त करते हैं, जिससे यह खंडित तालिका विचारों या संग्रह विचारों को प्रदर्शित करने के लिए त्रय बनाता है।
- Performance अनुकूलन: FRC हुड के तहत गलती और कैशिंग का उपयोग करता है। यह केवल आवश्यक डेटा प्राप्त करता है और वैकल्पिक रूप से प्रबंधित वस्तु संदर्भ को बचाया जाता है जब फिर से ड्राइंग से बचने के लिए लगातार कैश का उपयोग कर सकता है।
विस्तार में विधियाँ
नियंत्रक से पूरी तरह से लाभ उठाने के लिए, आपको ]] को लागू करना होगा। सबसे आम पैटर्न इन कॉलबैकों का उपयोग या ] के अंदर करना है, बैच-अपडेट करने के लिए यूआई। उदाहरण के लिए:
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.beginUpdates()
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>,
didChange anObject: Any,
at indexPath: IndexPath?,
for type: NSFetchedResultsChangeType,
newIndexPath: IndexPath?) {
switch type {
case .insert:
tableView.insertRows(at: [newIndexPath!], with: .fade)
case .delete:
tableView.deleteRows(at: [indexPath!], with: .fade)
case .update:
tableView.reloadRows(at: [indexPath!], with: .fade)
case .move:
tableView.moveRow(at: indexPath!, to: newIndexPath!)
@unknown default:
tableView.reloadData()
}
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.endUpdates()
}
यह पैटर्न यह सुनिश्चित करता है कि टेबल व्यू अंतर्निहित डेटा के साथ सिंक में बदलाव को दर्शाता है, जिससे फ़्लिकर या असंगति को रोका जा सकता है।
चरण-दर-चरण कार्यान्वयन
नीचे एक पूर्ण, उत्पादन-तैयार उदाहरण है जिसका उपयोग स्विफ्ट 5 का उपयोग करके किया जाता है, आईओएस 15+ को लक्षित करता है। हम एक साधारण इकाई को के साथ [[FLT: 13]] (स्ट्रिंग) और [[FLT: 14]] (Bool), और [[FLT: 15] (Date).
1. कोर डेटा स्टैक सेट करें
अपने या एक समर्पित (SwiftUI क्षुधा में आम तौर पर) में लगातार कंटेनर बना:
class PersistenceController {
static let shared = PersistenceController()
let container: NSPersistentContainer
init() {
container = NSPersistentContainer(name: "YourModelName")
container.loadPersistentStores { storeDescription, error in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}
container.viewContext.automaticallyMergesChangesFromParent = true
}
}
2. NSManageObject Subclass बनाएँ
Xcode के डेटा मॉडल संपादक का उपयोग कक्षा फ़ाइलों को उत्पन्न करने या उन्हें मैन्युअल रूप से बनाने के लिए करें। सुनिश्चित करें कि आपकी इकाई सही वर्ग मॉड्यूल सेटिंग का उपयोग करती है।
3. Fetch अनुरोध और FRC को कॉन्फ़िगर करें
अपने व्यू कंट्रोलर में, लाने के अनुरोध को सेट करें और प्राप्त परिणाम नियंत्रक को शुरू करें। इसे ] या एक दृश्य मॉडल की इनिट में करना सबसे अच्छा है।
lazy var fetchedResultsController: NSFetchedResultsController<Task> = {
let fetchRequest: NSFetchRequest<Task> = Task.fetchRequest()
let sortDescriptor = NSSortDescriptor(key: "dueDate", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
// Optional: limit results with batch size for large datasets
fetchRequest.fetchBatchSize = 20
let controller = NSFetchedResultsController(
fetchRequest: fetchRequest,
managedObjectContext: PersistenceController.shared.container.viewContext,
sectionNameKeyPath: "completionStatus", // e.g., a transient attribute or a computed property
cacheName: nil
)
controller.delegate = self
try? controller.performFetch()
return controller
}()
4. FRC के साथ टेबल व्यू ड्राइव
]
func numberOfSections(in tableView: UITableView) -> Int {
fetchedResultsController.sections?.count ?? 0
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sectionInfo = fetchedResultsController.sections![section]
return sectionInfo.numberOfObjects
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TaskCell", for: indexPath)
let task = fetchedResultsController.object(at: indexPath)
configure(cell, with: task)
return cell
}
नोटिस हम कभी नहीं कहते मैन्युअल रूप से - प्रतिनिधि विधियाँ हर प्रविष्टि, हटाने और अद्यतन संभालती हैं।
उन्नत उपयोग और सर्वश्रेष्ठ अभ्यास
थ्रेड सुरक्षा
कोर डेटा संदर्भ थ्रेड-सुरक्षित नहीं हैं। हमेशा सभी यूआई से संबंधित प्राप्त अनुरोधों और एफआरसी के लिए (जो मुख्य कतार पर चलता है) का उपयोग करते हैं। पृष्ठभूमि के काम के लिए, एक निजी कतार संदर्भ बनाएं और दृश्य संदर्भ में बदलाव लाएं। एकाधिक कतारों में उसी एफआरसी का उपयोग करने से बचें।
कैचिंग
] पैरामीटर खंड और ऑब्जेक्ट जानकारी को बनाए रखने के द्वारा प्रक्षेपण प्रदर्शन में सुधार कर सकता है। हालांकि, यदि आपका अनुरोध या डेटा मॉडल परिवर्तन हो जाता है, तो आपको भ्रष्टाचार से बचने के लिए कैश (]]]]] को हटाना होगा।
बड़े डेटासेट
] का उपयोग स्मृति में आने वाली वस्तुओं की संख्या को सीमित करने के लिए करें। इसके अलावा, सेटिंग पर विचार करें, केवल तभी यदि आपको प्रत्येक संपत्ति तक तत्काल पहुंच की आवश्यकता हो। रिश्ते-गहन डेटा के लिए, के साथ प्रीफेच करना बार-बार गलती को रोका जा सकता है।
SwiftUI
जबकि यूआईआईटी केंद्रित है, आप इसे ] में लपेटकर या नए ]]] संपत्ति रैपर (जो आंतरिक रूप से एक समान तंत्र का उपयोग करता है) का उपयोग करके अभी भी इसे स्विफ्टयूआई में जटिल गतिशील डेटा के लिए, [[FLT: 33] आमतौर पर पर्याप्त है, लेकिन FRC आपको एनिमेशन और बैचिंग पर बारीक-ग्रेन नियंत्रण देता है।
Them से बचने के लिए कैसे
- Forgetting : नियंत्रक इस विधि को कॉल करने तक लाने को क्रियान्वित नहीं करेगा। इसे एक बार करें, आमतौर पर प्रारंभिककरण के बाद सही।
- ]] ]]][FLT:>]]]] [[]]]]]][[FLT:>]]]]]]]]][[FLT:>]]]]]]][]]]]]]]][[[FLT:]]]]]]]]]]]]]]]]]]]]]]]]]]]]][[[[[[[[[[[[[[[[[[[[[[[[FLT]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
- ]]Incorrect सॉर्ट डिक्रिप्टर: यदि आपका अनुभाग नाम कुंजी पथ पहले प्रकार के डिक्रिप्टर से मेल नहीं खाता है, तो अनुभाग आदेश से बाहर दिखाई दे सकते हैं। ] में इस्तेमाल की गई विशेषता सुनिश्चित करें।
- ]]FRC के साथ का उपयोग: कॉलिंग जबकि FRC परिवर्तन को कम करने वाला है, दुर्घटनाग्रस्त हो सकता है। डेलिगेट विधियों को सभी UI अद्यतनों को संभालने दें।
- ] कोर डेटा संदर्भ को अनदेखा करना विफलताओं को बचाता है: यदि आप संदर्भ को बचाते हैं और एक त्रुटि होती है, तो FRC को सूचित नहीं किया जा सकता है। हमेशा त्रुटियों को संभालती है और ] का उपयोग करके पृष्ठभूमि संदर्भों में विचार करती है।
प्रदर्शन विचार
] पहले से ही कुशल है, लेकिन यहां अतिरिक्त अनुकूलन हैं:
- ]Use predicates बुद्धिमान: एक जटिल भविष्यवाणी प्रारंभिक लाता है धीमा कर सकते हैं। अनुक्रमित विशेषताओं का उपयोग करें जहां संभव हो।
- ]लिमिट ने गुण प्राप्त किया: यदि आपको केवल कुछ विशेषताओं की आवश्यकता है, तो को प्राप्त अनुरोध पर सेट करें।
- Batch अद्यतन: जब कई बदलाव किए, उन्हें एक ] ब्लॉक में लपेटकर प्रतिनिधि कॉलबैक की संख्या को कम करने के लिए।
- Avoid अनावश्यक दोष: यदि आप जानते हैं कि आप परिणाम सेट में सभी वस्तुओं तक पहुंचेंगे, तो उन्हें पहले से ही प्राप्त करने के लिए का उपयोग करें, लेकिन स्मृति के साथ सतर्क रहें।
कोर डेटा प्रदर्शन में एक गहरी गोता के लिए, Apple's कोर डेटा प्रदर्शन गाइड] देखें।
रियल-वर्ल्ड उदाहरण
उदाहरण 1: चैट अनुप्रयोग
एक संदेश एप्लिकेशन अधिकांश हाल के संदेश द्वारा क्रमबद्ध बातचीत की एक सूची प्रदर्शित करता है। नए आने वाले संदेश तुरंत दिखाई देना चाहिए। एक FRC का उपयोग करके, संपर्क दृश्य केवल वर्तमान उपयोगकर्ता की बातचीत संस्थाओं के लिए ही परिवर्तन की सदस्यता ले सकता है। दिनांक समूहों के संदेशों को "आज", "Yesterday", आदि में विभाजित करना।
उदाहरण 2: इन्वेंटरी प्रबंधन
एक ई-कॉमर्स ऐप श्रेणियों में उत्पादों को दिखाता है। जब शेयर स्तर पृष्ठभूमि सिंक से बदल जाता है, तो FRC स्वचालित रूप से UI को अपडेट करता है। को 50 में सेट करके, दृश्य हजारों वस्तुओं के साथ भी उत्तरदायी रहता है।
उदाहरण 3: श्रेणियों के साथ To-Do सूची
क्लासिक उदाहरण: "Overdue", "today", और "Upcoming" में समूहीकृत कार्य। ] और वर्तमान तारीख से संकलित एक क्षणिक व्युत्पन्न विशेषता हो सकता है। सुनिश्चित करें कि समान व्युत्पन्न मूल्य का उपयोग किसी तरह के वर्णनकर्ता में किया जाता है ताकि उन्हें गलत तरीके से बचने के लिए किया जा सके।
निष्कर्ष
कोर डेटा के संयोजन में माहिर होना और मजबूत, गतिशील आईओएस अनुप्रयोगों के निर्माण का एक आधारशिला है। एप्पल के ढांचे के लिए परिवर्तन ट्रैकिंग और यूआई सिंक्रनाइज़ेशन के भारी उठाने को बंद करके, आप बॉयलरप्लेट डेटा प्रबंधन कोड लिखने के बजाय एक महान उपयोगकर्ता अनुभव बनाने पर ध्यान केंद्रित कर सकते हैं।
चाहे आप एक विरासत UIKit ऐप को बनाए रखते हैं या ] के साथ SwiftUI को अपनाने वाले हों, सिद्धांत समान बने रहें: अपने ऑब्जेक्ट ग्राफ को समझें, अनुरोधों को ध्यान से कॉन्फ़िगर करें, और प्राप्त परिणाम नियंत्रक को यह सब कुछ दें। इस लेख में उल्लिखित प्रथाओं के साथ-साथ कैशिंग, थ्रेड सेफ्टी और प्रदर्शन ट्यूनिंग सहित - आपको समय-समय पर विकसित होने वाले किसी भी डेटासेट को संभालने के लिए अच्छी तरह से तैयार किया जाएगा।
आगे अन्वेषण के लिए, ]Ray Wenderlich के कोर डेटा ट्यूटोरियल और NSHipster लेख NSFetchedResultsController]] पर।