Xcode 11.2 अपडेट के बाद एप्लिकेशन क्रैश: _UITextLayoutView को कैसे हराएं
\n\nऐसा होता है: आप शांति से अपने प्रोजेक्ट पर काम कर रहे हैं, सब कुछ ठीक चल रहा है, टेस्ट पास हो रहे हैं, उपयोगकर्ता खुश हैं। और फिर — बैम! — आप Xcode को संस्करण 11.2 में अपडेट करते हैं, एप्लिकेशन चलाते हैं, और यह _UITextLayoutView नामक रहस्यमय त्रुटि के साथ क्रैश हो जाता है। परिचित लगता है? यदि हाँ — तो आप अकेले नहीं हैं। इस समस्या ने 2019 के अंत में Stack Overflow को सचमुच हिला दिया था (एक सप्ताह में हजारों व्यूज)।
इस लेख में मैं न केवल यह दिखाऊंगा कि इस बग को कैसे ठीक किया जाए, बल्कि यह भी समझाऊंगा कि यह क्यों होता है, इसका निदान कैसे करें और, सबसे महत्वपूर्ण, भविष्य में इसे कैसे रोकें। हम Swift पर लाइव उदाहरणों के साथ सब कुछ समझेंगे। चलिए शुरू करते हैं!
\n\n_UITextLayoutView क्या है?
\n\nसिद्धांत से शुरू करते हैं। _UITextLayoutView UIKit का एक आंतरिक (निजी) क्लास है, जो UITextView में टेक्स्ट रेंडरिंग के लिए जिम्मेदार है। Apple इसे सार्वजनिक रूप से दस्तावेज़ित नहीं करता है, इसलिए जब Xcode 11.2 में इस क्लास के साथ कुछ गलत हुआ, तो डेवलपर्स असमंजस में पड़ गए। त्रुटि कुछ इस तरह दिखती है:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_UITextLayoutView setFrame:]: unrecognized selector sent to instance 0x...'\n\nमुख्य वाक्यांश — "unrecognized selector sent to instance"। इसका मतलब है कि आप किसी ऑब्जेक्ट पर setFrame: मेथड को कॉल करने का प्रयास कर रहे हैं जो इसे सपोर्ट नहीं करता है। और चूंकि _UITextLayoutView एक निजी क्लास है, Xcode 11.2 से पहले यह अलग व्यवहार करता था।
जोखिम में कौन है?
\n\nसमस्या सभी में नहीं, बल्कि केवल कुछ शर्तों के तहत प्रकट होती है। यहाँ एक विशिष्ट परिदृश्य है:
\n- \n
- आप ऑटो-साइज़िंग (auto-sizing) सक्षम के साथ
UITextViewका उपयोग कर रहे हैं। \n - आपके पास एक कस्टम व्यू पदानुक्रम है जहाँ
UITextViewUIScrollViewयाUITableViewCellमें नेस्टेड है। \n - आप टेक्स्ट फील्ड के साथ सक्रिय रूप से इंटरैक्ट कर रहे हैं: स्क्रॉल करना, संपादित करना, फ़ॉन्ट बदलना। \n
यदि कम से कम एक बिंदु मेल खाता है — बधाई हो, आप जोखिम क्षेत्र में हैं। लेकिन चिंता न करें: इसका एक समाधान है, और यह सुरुचिपूर्ण है।
\n\nचरण 1: निदान — दोषी का पता लगाएं
\n\nइलाज करने से पहले, आइए सुनिश्चित करें कि समस्या वास्तव में _UITextLayoutView में है। Xcode कंसोल खोलें (View → Debug Area → Activate Console) और एप्लिकेशन चलाएं। यदि आप ऊपर दी गई त्रुटि के समान कोई त्रुटि देखते हैं — तो आप सही रास्ते पर हैं।
अतिरिक्त संकेत: क्रैश UITextView प्रदर्शित करने के पहले प्रयास पर या इसके अंदर स्क्रॉल करने पर होता है। यदि एप्लिकेशन लोड होने के तुरंत बाद क्रैश हो जाता है — तो संभवतः यही है।
चरण 2: सरल और त्वरित समाधान (उन लोगों के लिए जो जल्दी में हैं)
\n\nStack Overflow पर सबसे लोकप्रिय फिक्स UITextView के लिए ऑटोमैटिक रीसाइज़िंग को बंद करना है। यहाँ बताया गया है कि यह कैसे करें:
// आपके viewDidLoad या सेटअप मेथड में\ntextView.isScrollEnabled = false\ntextView.translatesAutoresizingMaskIntoConstraints = true\n\nलेकिन ध्यान दें! यह समाधान काम करता है, लेकिन यह टेक्स्ट के ऑटो-साइज़ को तोड़ देता है। यदि आपके लिए यह महत्वपूर्ण है कि UITextView कंटेंट के अनुसार गतिशील रूप से ऊँचाई बदले — तो यह विकल्प उपयुक्त नहीं होगा। आइए गहराई से देखें।
चरण 3: उन्नत समाधान — layoutSubviews को ओवरराइड करना
\n\nApple ने Xcode 11.2.1 में एक पैच जारी किया, लेकिन यदि आप किसी कारण से 11.2 पर बने हुए हैं, या एक सार्वभौमिक समाधान चाहते हैं, तो यहाँ वह है जो आपको करना चाहिए।
\n\nUITextView का एक सबक्लास बनाएं और layoutSubviews मेथड को ओवरराइड करें:
import UIKit\n\nclass FixedTextView: UITextView {\n override func layoutSubviews() {\n super.layoutSubviews()\n // बग के कारण होने वाली अतिरिक्त सबव्यू से लेयर को साफ़ करें\n self.subviews.forEach { subview in\n if subview.isKind(of: NSClassFromString("_UITextLayoutView") ?? UIView.self) {\n