2012-07-16 24 views
11

मैंने एनएसआरएल कैश पर अपने सिर को चिल्लाते हुए पूरी तरह से काफी समय बिताया है, इसलिए मैं उम्मीद में इस सलाह की पेशकश करता हूं कि अन्य मेरी दुर्भाग्य से बच सकते हैं।एनएसआरएल कैश आईओएस 5 पर असंगत परिणाम प्रदान करता है, प्रतीत होता है कि यादृच्छिक

यह सब काफी उचित रूप से बंद हो गया। मेरा नया ऐप प्रोजेक्ट केवल आईओएस 5 और उससे ऊपर का लक्ष्य रखता है, इसलिए मैंने सोचा कि मैं अपने सभी वेब कैशिंग आवश्यकताओं के लिए नए NSURLCache कार्यान्वयन का लाभ उठा सकता हूं। मुझे कुछ विशेष कार्यों को संभालने के लिए NSURLCache के कस्टम सबक्लास की आवश्यकता थी, लेकिन सभी को एपीआई द्वारा मददगार रूप से समर्थित लग रहा था। दस्तावेज की एक त्वरित पढ़ा है, और मैं दौड़ के लिए रवाना कर रहा हूँ:

[NSURLCache setSharedURLCache:[[MyCustomCache alloc] initWithMemoryCapacity:8 * 1024 * 1024 //8mb 
                    diskCapacity:32 * 1024 * 1024 // 32mb 
                     diskPath:@"webcache.db"]]; 

मैं समझ एक 8MB कैश शुरू करने के लिए ठीक है, और मैं एक बड़ा डिस्क कैश के साथ इसे वापस कर देंगे तो हम में से अधिक सेवा कर सकते हैं स्थानीय रूप से हमारी बड़ी छवियों। मैं NSRLConnection का उपयोग करने के लिए अपने शेष नेटवर्क कोड को हुक करता हूं (वास्तव में, मैंने MKNetworkKit का उपयोग किया, लेकिन यह अप्रासंगिक साबित हुआ), और मेरे कैश से बड़ी चीजों की अपेक्षा करता है। निश्चित रूप से, कैश किए जाने वाले सभी अनुरोधों को कर्तव्य से बचाया जा रहा है, और प्रतिक्रियाएं जब वे कैश से परोसे जाते हैं तो जल्दी से वापस उड़ रहे हैं। यह समुद्री डाकू के समुद्री डाकू का नियमित उत्पादन है जो मेरे नेटवर्किंग स्टैक में इतनी कड़ी उड़ान भर रहा है।

कुछ जोड़ने के अलावा। कैश से परोसा जा सकता है अनुरोध अभी भी नेटवर्क पर बाहर जा रहे हैं। सिवाय जब वे नहीं हैं। यह पूरी तरह यादृच्छिक और अंतःक्रियात्मक प्रतीत होता है कि कैश वास्तव में अनुरोध करने के लिए उपयोग किया जाता है या नहीं। मैं अपने बालों को निराशा में फाड़ता हूं और सचमुच सब कुछ पता लगाने की कोशिश कर रहा हूं कि क्या हो रहा है। मैं परीक्षण ऐप्स बनाता हूं, पूरे स्थान पर ब्रेकपॉइंट्स सेट करता हूं, पैकेट निशान के माध्यम से फाड़ता हूं, इंटरनेट पर हर शब्द को पढ़ता हूं जो NSRLCache का उल्लेख करता है, कैश-कंट्रोल हेडर के साथ प्रयोग करता है, कोड को टिप्पणी करता है, मेरे सबक्लास को बाईपास करता है, और यहां तक ​​कि दर्दनाक रूप से ट्रेसिंग का सहारा लेता है NSURLCache और उसके CFNetworking मित्रों के लिए असेंबली यह समझने की कोशिश करने के लिए कि रहस्यमय तर्क नीचे क्या है। मैं बड़े पैमाने पर एआरएम और उद्देश्य-सी कॉलिंग सम्मेलनों के बारे में अपने ज्ञान में सुधार करता हूं और निम्न स्तर के डिबगिंग के बारे में काफी कुछ सीखता हूं, लेकिन वास्तव में यह पता लगाने में कहीं भी नहीं मिलता कि क्या हो रहा है। पूरी चीज आईओलांथे के Nightmare Song की तरह समुद्री डाकू राजा की सौहार्दपूर्ण तानाशाही की तुलना में बहुत अधिक महसूस कर रही है और मैं इसे दूर फेंकने के कगार पर काफी अधिक हूं।

टीएल/डीआर संस्करण: NSURLCache काम करता प्रतीत होता है, लेकिन यादृच्छिक रूप से कैश किए गए परिणामों को वापस नहीं करता है, भले ही यह उपलब्ध हो।

+0

क्या आप NSURLConnection, UIWebView, या दोनों के लिए कैशिंग का उपयोग करने का प्रयास कर रहे हैं? मैंने कुछ महीने पहले डब्ल्यूडब्ल्यूडीसी में एक सफारी डेवलपर के साथ UIWebView कैशिंग पर चर्चा की। उन्होंने कहा कि एक दोहरी परत कैश है। अपने स्वयं के डिबगिंग परीक्षणों से, मैंने पाया है कि ओएस-स्तरीय सफारी कैश की जांच करने से पहले '+ [NSURLCache sharedURLCache]' चेक किया गया है। हालांकि, प्रतिक्रिया आपके ऐप के साझा कैश में कैश नहीं की जाएगी, और कौन जानता है कि ओएस स्तर कैश कैसे व्यवहार करता है। – goldierox

+0

दिलचस्प। मैंने केवल NSRLConnection पक्ष पर ध्यान केंद्रित किया है, क्योंकि हमारा ऐप UIWebView का अधिक उपयोग नहीं करता है। मुझे याद है कि ओएस-स्तरीय सफारी कैश का उपयोग ऐप्स द्वारा नहीं किया गया था, लेकिन मुझे विश्वास है कि यह मामला नहीं है, खासकर UIWebView के लिए। –

उत्तर

9

आखिरकार, मैं उन सभी बिट्स का एक अलग क्रमपरिवर्तन करने का प्रयास करता हूं जिनके साथ मैं झुका रहा हूं। मैंने मेमोरी और डिस्क कैश आकार दोनों को 8 एमबी पर सेट किया है।

लो और देखो, सभी अजीबता दूर हो जाती है! कैश होने वाला माना जाने वाला सब कुछ बचाया जा रहा है। और कैश से आने वाली हर चीज़ को नेटवर्क अनुरोधों के बिना सेवा मिल रही है।

ऐसा लगता है कि आईओएस 5 में NSURLCache कार्यान्वयन अभी भी पूरा नहीं हुआ है। यह डिस्क और मेमोरी कैश का उपयोग करता है (आईओएस 4 और इससे पहले, जो केवल इन-मेमोरी कैश को लागू करता है), लेकिन जब कोई अनुरोध याद आती है तो यह वास्तव में डिस्क कैश में मेमोरी कैश से गुजरती नहीं है। इस प्रकार, यह मूल रूप से अंधे भाग्य है (अच्छी तरह से, आपके सभी अन्य नेटवर्क और कैश उपयोग से प्रभावित अंधे भाग्य) चाहे दी गई प्रतिक्रिया स्मृति में हो या सही समय पर न हो। यह शायद डिवाइस पर फ्लैश मेमोरी फ़ाइल आईओ को कम करने के लिए उपयोगी है, लेकिन यदि आप वर्ग से तर्कसंगत व्यवहार की अपेक्षा करते हैं तो बेहद अप्रिय है।

और हंसते हुए गीत और मज़ेदार नृत्य के साथ, मैं अपने दो-लाइन फिक्स में चेक करता हूं और बार के लिए जल्दबाजी करता हूं, अंततः इस ज्ञान को एसओ (और एक ऐप्पल बग रिपोर्ट) के साथ साझा करने की उम्मीद में साझा करता हूं कि किसी और के पास नहीं है इस दर्द से फिर से जाने के लिए।

दुःख की इस कहानी का नैतिक: अजीब और बुरी चीजें तब होती हैं जब आप आईओएस 5 पर एनएसआरएल कैश का उपयोग स्मृति क्षमता से बड़ी डिस्क क्षमता के साथ करने का प्रयास करते हैं। ऐसा मत करो। और जादुई परी के दुश्मन बनाने से बचें।

+0

मुझे खेद है कि यह मेरे लिए काम नहीं करता है। – bogardon

+0

यह मेरे लिए चीजों को बहुत बेहतर बना देता है, लेकिन बाद में भी मुझे कुछ अजीबता थी। ऐसा लगता है कि NSURLCache के साथ कुछ गंभीर सिंक्रनाइज़ेशन समस्याएं (?) हैं। मैंने एक रडार दायर किया है, और इस बीच, मेरी सभी छवि कैशिंग को एसडीवेब इमेज (https://github.com/rs/SDWebImage) के एक सुंदर हैक किए गए कांटा पर ले जाना घायल हो गया है, जो कम से कम निश्चित रूप से व्यवहार करता है। –

2

FWIW यहाँ मेरा अंतिम समाधान है:

https://gist.github.com/3245415

यह FMDB उपयोग करने की आवश्यकता है, लेकिन परिणाम बहुत अच्छे हैं।

+0

अच्छा दृष्टिकोण। मैंने ऐसा कुछ करने की कोशिश करने के बारे में सोचा, लेकिन आखिरकार एसक्यूएलएट डीबी के साथ मिलकर काम करने से सावधान था जब यह स्पष्ट रूप से अप्रत्याशित रूप से व्यवहार कर रहा था। मैं आपके फिक्स के साथ सिंक्रनाइज़ेशन समस्याओं के बारे में चिंतित हूं, हालांकि शायद यह सब अभ्यास में काम करता है। जैसा कि मैंने उपर्युक्त कहा है, मैं छवि कैशिंग को संभालने के लिए एसडीवेब इमेज (पुल अनुरोध देखें) के एनएससीएच-बैकड कांटा का उपयोग कर रहा हूं और परिणामों से काफी खुश हूं। –

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