2014-04-28 6 views
5

मैं अपने प्रोजेक्ट के रेस्टकिट और कोर डेटा के उपयोग को सर्वोत्तम रूप से प्रारूपित करने का प्रयास कर रहा हूं। ऐसी कुछ चीजें हैं जिन्हें मैंने काम किया है, लेकिन मुझे लगता है कि उन्हें खराब और संभावित रूप से थ्रेड असुरक्षित लागू किया गया है ... मेरे पास एक ऐसा ऑब्जेक्ट है जो मेरे सभी डेटा ट्रांसफर, स्टोरेज इत्यादि का प्रबंधन करता है, जिसमें एक फ़ंक्शन है जो restkit सेट अप करता है। मेरे पास एक इंस्टेंस वैरिएबल है जो मैं RKObjectManager के लिए उपयोग करता हूं, और इस सेटअप फ़ंक्शन में मैं ऑब्जेक्टस्टोर बना देता हूं, सभी विशेषता मैपिंग सेट करता हूं, लगातार स्टोर बना देता हूं, - सामान्य सामान्यकिट सेटअप कोड। इस फ़ंक्शन के बाहर, इस ऑब्जेक्ट के लिए उपलब्ध एकमात्र चीज _objectManager इंस्टेंस वैरिएबल है, जिसे मैं NSFetchRequests और इस तरह के लिए उपयोग कर रहा हूं।रेस्टकिट और प्रबंधित ऑब्जेक्ट संदर्भ

दो चीजें हैं जिन्हें मैं सुनिश्चित करना चाहता हूं कि मैं ठीक से कार्यान्वित कर रहा हूं, प्रबंधित वस्तुओं को ला रहा हूं, और प्रबंधित वस्तुओं में बचत परिवर्तन कर रहा हूं।

अगर मैं एक वस्तु पर एक संपत्ति को अपडेट करना चाहते, मैं यह कर दिया गया है:

object.whatever = @"something here"; 

NSError *error; 
if (![object.managedObjectContext save:&error]) { 
    // log the error here 
} 

इस अद्यतन करने के लिए/एक वस्तु पर एक संपत्ति को बचाने के लिए उचित तरीका है? ऑब्जेक्ट के प्रबंधित ऑब्जेक्ट संदर्भ को एक्सेस करना सीधे कोड में किसी भी बिंदु पर करने के लिए सहेज रहा है, या यह ऐसा कुछ है जो केवल पृष्ठभूमि/अग्रभूमि में किया जाना चाहिए? मेरा वर्तमान कार्यान्वयन संभावित रूप से पृष्ठभूमि और अग्रभूमि दोनों में बुलाया जा सकता है और मैं बस यह सुनिश्चित करना चाहता हूं कि यह स्वीकार्य है।

जब मैं एक वस्तु लाने के लिए चाहते हैं, मैं एक समारोह है कि एक इकाई के नाम लेता है, विधेय की एक सरणी, और पैरामीटर के रूप में एक तरह से वर्णनकर्ता लिखा तो यह पुन: उपयोग किया जा सकता है:

NSManagedObjectContext *managedObjectContext = // I DONT KNOW WHAT TO PUT HERE! // 

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 

    NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:managedObjectContext]; 
    [fetchRequest setEntity:entity]; 

    NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicates]; 
    [fetchRequest setPredicate:compoundPredicate]; 

    NSError *error; 
    NSArray *fetchedRecords = [managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

    if (error) { 
     // log error 
    } 

    // if we were given a sort descriptor, sort the array appropriately 
    if (sortDescriptor) { 
     fetchedRecords = [fetchedRecords sortedArrayUsingDescriptors:@[sortDescriptor]]; 
    } 

    return fetchedRecords; 

मेरे समस्या यहाँ है सही प्रबंधित ऑब्जेक्ट संदर्भ बनाना/एक्सेस करना। मुझे यह कैसे करना चाहिए? मैं RKObjectManager मैं इस तरह के रूप से पहले बनाए गए पर कुछ संपत्ति एक्सेस करते हैं:

_objectManager.managedObjectStore.mainQueueManagedObjectContext 

या कि क्योंकि इसके मुख्य थ्रेड के लिए सुरक्षित थ्रेड नहीं है? यह सुनिश्चित करने के लिए मैं क्या कर सकता हूं कि मैं सही प्रबंधित ऑब्जेक्ट संदर्भ का उपयोग कर रहा हूं, और यह थ्रेड सुरक्षित है? मैं उपयोग कर रहा था:

_objectManager.managedObjectStore.persistentStoreManagedObjectContext 

लेकिन मुझे बताया गया था यह निश्चित रूप से नहीं सबसे अच्छा अभ्यास था और सुरक्षित थ्रेड नहीं कर रहा था, तो मैं सबसे अच्छा समाधान निर्धारित करने के लिए कोशिश कर रहा हूँ।

संपादित करें - शायद जब भी मैं वस्तुओं को लाने के लिए संदर्भ प्राप्त करने के लिए इस समारोह को कॉल कर सकता हूं?

- (NSManagedObjectContext *)getManagedObjectContext { 
    if ([NSThread isMainThread]) { 
     return _objectManager.managedObjectStore.mainQueueManagedObjectContext; 
    } 
    else { 
     return [_objectManager.managedObjectStore newChildManagedObjectContextWithConcurrencyType:NSPrivateQueueConcurrencyType tracksChanges:YES]; 
    } 
} 

उत्तर

5

बचत के लिए, बजाय इस की:

if (![object.managedObjectContext save:&error]) { 

आपको क्या करना चाहिए:

if (![object.managedObjectContext saveToPersistentStore:&error]) { 

ताकि इन परिवर्तनों को डिस्क पर स्टोर के लिए श्रृंखला कायम कर रहे हैं। आपको केवल उस थ्रेड पर ऐसा करना चाहिए जो प्रबंधित ऑब्जेक्ट को बनाया/लाया गया हो (इस प्रकार एमओसी का थ्रेड स्वामित्व बनाए रखा जाता है)।

फोरग्राउंड/पृष्ठभूमि इतना महत्वपूर्ण नहीं है कि प्रत्येक थ्रेड द्वारा एमओसी का उपयोग किया जाए। यदि एमओसी थ्रेड स्वामित्व का सम्मान किया जाता है तो आपको ठीक होना चाहिए।

वही लाने पर लागू होता है। यूआई अपडेट के लिए, आपको मुख्य थ्रेड और mainQueueManagedObjectContext का उपयोग करना होगा। आपको सीधे persistentStoreManagedObjectContext का उपयोग नहीं करना चाहिए।मनमाने ढंग से पृष्ठभूमि धागे के लिए आपको प्रबंधित ऑब्जेक्ट स्टोर से आपके लिए एक नया बच्चा प्रबंधित ऑब्जेक्ट संदर्भ बनाने और उस का उपयोग करने के लिए कहा जाना चाहिए।

+0

आप बेहद सहायक रहे हैं! मेरी मुख्य समस्या यह है कि यह फ़ंक्शन इतना सामान्य बना दिया गया है कि यह नहीं जानता कि यह किस धागे पर चल रहा है। क्या यह निर्धारित करने का कोई आसान तरीका है ताकि मैं जान सकूं कि mainQueueManagedObjectContext का उपयोग करना है या नया बच्चा संदर्भ बनाना है या नहीं? – Mike

+1

'[NSThread isMainThread] 'है, लेकिन यह नहीं पता कि आप कौन से पृष्ठभूमि थ्रेड पर हो सकते हैं। कभी-कभी आप इस तरह की जानकारी को स्टोर करने के लिए 'थ्रेड डिक्शनरी' का उपयोग कर सकते हैं ... – Wain

+0

जो मुझे लगता है कि उन आवश्यकताओं को पूरा करने के लिए ऊपर एक संपादन जोड़ा गया है। अगर मुझे यह सरल परिवर्तन ठीक है तो मुझे बताएं। – Mike

संबंधित मुद्दे