2010-04-09 20 views
7

के साथ ऑब्जेक्ट्स की एक सरणी डालने का मेमोरी प्रभावी तरीका मैं एक आईफोन एप्लिकेशन के लिए कोड के टुकड़े पर काम कर रहा हूं जो सर्वर से डेटा का एक गुच्छा लाता है और क्लाइंट पर ऑब्जेक्ट बनाता है। यह लगभग 40,000 वस्तुओं को बनाने के समाप्त होता है। वे उपयोगकर्ता को प्रदर्शित नहीं होते हैं, मुझे बस एनएसएमएनेज ऑब्जेक्ट के उदाहरण बनाने और लगातार स्टोरेज में स्टोर करने की आवश्यकता है।कोर डेटा

क्या मैं यह सोचने में गलत हूं कि ऐसा करने का एकमात्र तरीका एक वस्तु बनाना है, फिर संदर्भ को सहेजना है? ऑब्जेक्ट्स को एक साथ बनाने के लिए सबसे अच्छा है, फिर किसी भी तरह से उन्हें सेट या सरणी में संग्रहीत और संग्रहीत करने के बाद संदर्भ में सहेज लें? यदि हां, तो क्या कोई यह उदाहरण के लिए कुछ उदाहरण कोड दिखा सकता है कि यह कैसे किया जाता है या कोड को दिशा में इंगित करता है जहां यह किया जाता है?

ऑब्जेक्ट्स स्वयं स्ट्रिंग या पूर्णांक विशेषताओं वाले अपेक्षाकृत सीधे आगे मॉडल हैं और इसमें कोई जटिल संबंध नहीं है।

उत्तर

5

किसी भी मामले में, प्रत्येक ऑब्जेक्ट डालने के बाद सहेजें, या भयानक प्रदर्शन के लिए तैयार रहें।

यहां पहला कोड है जो मैं पहली लॉन्च पर कोर डेटा भंडार को पॉप्युलेट करने के लिए उपयोग करता हूं।

#define MAX_UNSAVED_AIRPORTS_BEFORE_SAVE 1000 
int numAirports = 0; 
int numUnsavedAirports = MAX_UNSAVED_AIRPORTS_BEFORE_SAVE; // *** bug. see below 
for (NSDictionary *anAirport in initialAirports) { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    Airport *newAirport = [NSEntityDescription insertNewObjectForEntityForName:@"Airport" inManagedObjectContext:managedObjectContext]; 

    newAirport.city   = [anAirport objectForKey:@"city"]; 
    newAirport.code   = [anAirport objectForKey:@"code"]; 
    newAirport.name   = [anAirport objectForKey:@"name"]; 
    newAirport.country_name = [anAirport objectForKey:@"country_name"]; 
    newAirport.latitude  = [NSNumber numberWithDouble:[[anAirport objectForKey:@"latitude"] doubleValue]]; 
    newAirport.longitude = [NSNumber numberWithDouble:[[anAirport objectForKey:@"longitude"] doubleValue]]; 
    newAirport.altitude  = [NSNumber numberWithDouble:[[anAirport objectForKey:@"altitude"] doubleValue]]; 

    numAirports++; 
    numUnsavedAirports++; 
    if (numUnsavedAirports >= MAX_UNSAVED_AIRPORTS_BEFORE_SAVE) { 
     if (![managedObjectContext save:&error]) { 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
      abort(); 
     } 
     numUnsavedAirports = 0; 
    } 
    [pool release]; 
} 

लूप के बाद आखिरी बार सहेजना भी न भूलें।

भी जागरूक एक बग मौजूद है कि एक दुर्घटना के लिए नेतृत्व करेंगे, तो निम्न स्थितियों के सभी तीन से मुलाकात कर रहे हो:

  1. भंडार खाली है
  2. आप वर्गों के साथ एक UITableView है
  3. आपका पहले सहेजने से एक से अधिक ऑब्जेक्ट बचाता है।

उपरोक्त कोड में समाधान आदेश यकीन है कि पहले बचाने पहले डालने के बाद क्या होता बनाने के लिए MAX_UNSAVED_AIRPORTS_BEFORE_SAVE को numUnsavedAirports प्रारंभ करने में है।

मुझे उम्मीद है कि इससे मदद मिलती है।

1

शायद एक ऑब्जेक्ट बनाना और संदर्भ को सहेजना बेहतर है।

आपके पास 40k ऑब्जेक्ट्स हैं। आइए मान लें कि एक एकल NSManagedObject बनाना x समय इकाइयां लेता है। 40kx समय इकाइयों शायद मापने योग्य है। ऑब्जेक्ट निर्माण हो रहा है, उपयोगकर्ता किसी कारण से ऐप छोड़ सकता है; उपयोगकर्ता अप्रत्याशित हैं। अगली बार जब आपका ऐप शुरू होता है, तो आप फिर से प्रक्रिया के माध्यम से जाते हैं। उपयोगकर्ता को ऐप छोड़ने और उस काम को खोने के लिए केवल 39,999 वें ऑब्जेक्ट बनाने के लिए वांछनीय नहीं होगा।

यदि आपका ऐप प्रत्येक ऑब्जेक्ट बनाने और सहेजने के लिए था, तो आप इस प्रक्रिया को थोड़ा तेज कर सकते हैं। ऐप शुरू होता है और यह देखने के लिए जांच करता है कि क्या यह आखिरी बार दौड़ने में सक्षम था या नहीं। यदि कार्य अपूर्ण था, तो यह कहां से निकल गया था इसे लेने का प्रयास कर सकता था।

एकल वस्तु निर्माण और सहेजने की विधि को पूरा करने में लंबा समय लग सकता है लेकिन कार्य को पूरा करने की अधिक संभावना होगी।

स्मृति खपत के मामले में, यह आपके ऐप की स्मृति स्थिति को भी कम करता है। संदर्भ मेमोरी में 40k ऑब्जेक्ट्स को ट्रैक नहीं कर रहा है।

+2

व्यक्तिगत रूप से प्रत्येक ऑब्जेक्ट को सहेजने से भयानक प्रदर्शन होगा। –

3

प्रत्येक ऑब्जेक्ट के बाद सहेजना बहुत खराब प्रदर्शन करेगा। आपके पास शायद हर 100 बचाता है (परीक्षण मीठा स्थान निर्धारित करेगा) और उसके बाद उपयोगकर्ता को छोड़ने पर प्रसंस्करण में आप कहां हैं, इसका ट्रैक रखें।

आपको राज्य को स्टोर करने के लिए बाहर निकलने पर समय मिलता है ताकि आप आसानी से डेटा प्रोसेसिंग (100 सहेजे गए 5 ब्लॉक) में अपनी स्थिति को स्टोर कर सकें और जहां आपने छोड़ा था वहां वापस ले जाएं।

व्यक्तिगत रूप से प्रत्येक ऑब्जेक्ट को सहेजना डिस्क को हथियार देगा और ऐप को क्रॉल में धीमा कर देगा।

+0

इस सही सलाह के अलावा, आपको स्मृति पदचिह्न को कम करने के लिए सहेजने के बाद प्रबंधित ऑब्जेक्ट कॉन्टेक्स्ट को रीसेट करने पर भी विचार करना चाहिए। लेकिन सावधान रहें कि संदर्भ को रीसेट करने से आप उस संदर्भ में किसी भी मध्यवर्ती परिणाम खो देते हैं। जैसे बैच किए गए fetchResults भी चला गया है। – Bjinse

+0

प्रासंगिक ऐप्पल दस्तावेज़ यहां हैं: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdImporting.html – Bjinse