2011-09-02 22 views
5

मेरे पास एक फॉर्म में आरटीएल स्ट्रीमिंग में एक रनटाइम त्रुटि हो रही है, जिससे TReader.ReadRootComponent करते समय अपवाद EClassNotFound उठाया जा सकता है। विशेष त्रुटि संदेश "क्लास TActionList नहीं मिला" है।रनटाइम पर उठाए गए EClassNotFound का वास्तव में क्या मतलब है जब प्रश्न में कक्षा संकलित और लिंक समय पर है, और स्पष्ट रूप से कोड में है?

क्या अजीब है:

  1. मेरा मुख्य रूप क्रिया सूची का उपयोग करता है।
  2. मज़े के लिए, मैंने इसे ठीक करने का प्रयास करने के लिए, मेरे प्रोजेक्ट में ActnList.pas (वीसीएल स्रोत फ़ोल्डर से) जोड़ा।

यह कुछ ऐसा होता है जब मैं कुछ मिनट पहले काम कर रहा था। मैंने जो परिवर्तन किया है वह कुछ उप-फ्रेम कोड में था: मैंने अपने सभी कार्यान्वयन अनुभाग कोड को ifdef मार्कर के साथ हटा दिया, क्योंकि मैं इकाई परीक्षण और प्रोटोटाइप के लिए कुछ फ्रेमों का मज़ाक उड़ा रहा हूं।

मैंने प्रोजेक्ट में एक्शन लिस्ट क्लास जोड़ने की कोशिश की, और मैंने विभिन्न कंपाइलर और लिंक विकल्पों के साथ और बिना कोशिश की, और फिर भी, मुझे अभी भी यह अपवाद मिलता है। जाहिर है कुछ अजीब है। इस समस्या को पाने के लिए एक और अजीब तरीका होना चाहिए।

वास्तव में, ऐसा लगता है कि वास्तव में कुछ अजीब चल रहा है। जब इस त्रुटि उठाया है, मैं निम्नलिखित कॉल स्टैक मिलती है:

rtl.Classes.ClassNotFound('TActionList') 
rtl.Classes.TReader.FindComponentClass(???) 
rtl.Classes.FindExistingComponent 
rtl.Classes.TReader.ReadComponent(nil)  /// NIL!? WHAT!!!!! 
rtl.Classes.TReader.ReadDataInner(???) 
rtl.Classes.TReader.ReadData(???) 
rtl.Classes.TComponent.ReadState(???) 
vcl.Controls.TControl.ReadState(???) 
vcl.Controls.TWinControl.ReadState($60B9CF0) 
vcl.Forms.TCustomForm.ReadState(???) 
rtl.Classes.TReader.ReadRootComponent($606EB90) 
rtl.Classes.TStream.ReadComponent($606EB90) 
rtl.Classes.InternalReadComponentRes(???,???,$606EB90) 
rtl.Classes.InitComponent(TComplexFormContainingFrames) 

ऐसा लगता नहीं के बराबर जानबूझकर है, TReader.ReadDataInner में (उदाहरण: TComponent):

 while not EndOfList do ReadComponent(nil); 

अद्यतन: मेरा मानना ​​है कि इस सवाल का जवाब "सीरियलाइजेशन संदर्भ" को समझना है क्योंकि मेसन ने उल्लेख किया है। और, अब मेरी अपनी मूर्खता स्वीकार करने का समय है: मैंने परियोजना से फ्रेम के माता-पिता को हटा दिया, यह समझ में नहीं आया कि यह फ्रेम का मूल था। मैंने TMyFrameParent के लिए TMyFrameParent = class(TFrame) के रूप में प्रकार की घोषणा को दबाकर गुम होने के दौरान काम किया, और इससे बदले में स्थिति की स्थिति बढ़ गई। मैं यहां सवाल छोड़ रहा हूं क्योंकि मुझे लगता है कि यह भविष्य में वास्तव में आसान हो सकता है जब यह अपवाद आर्केन मामलों में होता है, और इसे कैसे ठीक किया जाए। विशेष रूप से, मेसन के पास "क्रमबद्ध संदर्भ" के बारे में जानकारी का एक दिलचस्प दिलचस्प हिस्सा है और वे कक्षा-नाम-खोज पर कैसे लागू होते हैं।

+1

शून्य केवल एक मौजूदा उदाहरण में पढ़ने के बजाय एक नया उदाहरण तत्काल करने के लिए ReadComponent को सिग्नल करता है। –

उत्तर

6

इसका मतलब है कि कक्षा वर्तमान deserialization संदर्भ में नहीं मिला था। सभी मौजूदा वर्ग सभी लोडिंग के लिए पंजीकृत नहीं हैं। प्रत्येक फॉर्म क्लास में आरटीटीआई होता है जिसमें इसका उपयोग घटकों के संदर्भ होते हैं। कक्षाएं आप के साथ उपयोग करना चाहते हैं रजिस्टर करने के लिए

TMyForm = class(TForm) 
    ActionList: TActionList; 
    OtherComponent: TSomeComponent; 
private 
    //whatever 
public 
    //whatever 
end; 
2

उपयोग Classes.RegisterClass: इस काम यह सुनिश्चित करना है कि अपने फार्म (या फ्रेम, अगर यह एक फ्रेम है) निजी टैग से पहले कम से कम एक TActionList वाणी प्राप्त करने के लिए स्ट्रीमिंग सिस्टम। दस्तावेज़

फ़ॉर्म वर्ग और घटक वर्ग जिन्हें फॉर्म घोषणा (उदाहरण चर) में संदर्भित किया गया है, स्वचालित रूप से पंजीकृत हैं। किसी एप्लिकेशन द्वारा उपयोग किए जाने वाले किसी भी अन्य वर्ग को रजिस्टर क्लास को कॉल करके स्पष्ट रूप से पंजीकृत होना चाहिए यदि उदाहरण सहेजे जाएंगे। कक्षाएं पंजीकृत होने के बाद, उन्हें घटक स्ट्रीमिंग सिस्टम द्वारा लोड या सहेजा जा सकता है।

+0

तो किसी फ्रेम के मामले में जो किसी अन्य फ्रेम से विरासत में है, शायद यह बताता है कि क्लासेस.रेजिस्टर क्लास को कभी क्यों नहीं कहा गया था, क्योंकि फ्रेम के .dfm में केवल "विरासत x" प्रविष्टि है, न कि "ऑब्जेक्ट एक्स" प्रविष्टि। –

+0

कुछ ख़राब है ... अगर प्रोजेक्ट में पैरेंट फ्रेम नहीं था, तो स्ट्रीमिंग सिस्टम ने TActionList क्लास को कैसे देखा? क्योंकि वंशज फ्रेम के लिए dfm खाली थे (यानी एक्शनलिस्ट नहीं है), है ना? – ain

1

ऐसा लगता है कि यह होता है जब आप एक अन्य परियोजना के लिए एक परियोजना से एक फ्रेम प्रतिलिपि बनाएँ, और उस फ्रेम कुछ से विरासत है, और आप नकली विरासत, लेकिन फ्रेम DFM में "प्राप्त" आइटम विवरण छोड़ देते हैं, आइटम इस तरह:

inherited ActionList: TActionList 
    Left = 520 
    Top = 576 
end 
"वर्तमान अक्रमांकन संदर्भ" में

यह बदले परिणामों में है कि मेसन बारे में बात की, क्लास वाली नहीं। एक फिक्स सभी उपरोक्त मामलों में ऑब्जेक्ट में स्थानांतरित करना है।