2014-07-04 9 views
9

मैं एक निब फ़ाइल से एक विंडो नियंत्रक ऑब्जेक्ट प्रारंभ करना चाहता हूं, काफी आसान है? लेकिन मैं बस इसे काम नहीं कर सकता।स्विफ्ट में एनएसविंडो कंट्रोलर कैसे शुरू करें?

ObjC में अपने पिछले अनुभव के अनुसार, मैं निम्नलिखित कोड नीचे लिखा है:

var myWindowController: MyWindowController = MyWindowController() 
myWindowController.showWindow(self) 
myWindowController.window.makeKeyAndOrderFront(nil) 

:

init() { 
    super.init(windowNibName: "SplitWindowController") 
} 

और एप्लिकेशन प्रतिनिधि फ़ाइल में, मैं बस init और विंडो प्रदर्शित करता है लेकिन संकलक मुझे यह त्रुटि देता है: Must call a designated initializer of the superclass 'NSWindowController'। और NSWindowController परिभाषा के स्विफ्ट संस्करण के अनुसार, केवल 3 नामित प्रारंभिक, init(), init(window), init(coder) हैं। मुझे नहीं पता कि आगे क्या करना है। क्या मैं एक निब फ़ाइल से NSCoder का निर्माण करूंगा, जो मुझे नहीं पता कि कैसे करना है?

init(window: NSWindow!) 
init(coder: NSCoder!) 

एक उपवर्ग बनाते समय, आप अपने सुपर क्लास के नामित प्रारंभकर्ता आह्वान करना चाहिए:

+0

@George यहाँ देख आपके प्रश्न का उत्तर दिया: [उपवर्गीकरण NSWindowController] [1] [1]: http: // stackoverflow।कॉम/प्रश्न/24220638/उपclassing-nswindowcontroller-in-swift-and-initwindownibname – mqueue

उत्तर

4

NSWindowController 2 नामित initializers है। एक्सकोड के हाल के संस्करण इसे लागू करते हैं। या तो अंतर्निर्मित भाषा तंत्र (स्विफ्ट) के माध्यम से या NS_DESIGNATED_INITIALIZER मैक्रो (उद्देश्य-सी) के माध्यम से।

स्विफ्ट अतिरिक्त रूप से आवश्यक है कि आप सुपरक्लास नामित प्रारंभकर्ता को कॉल करें जब आप सुविधा प्रारंभकर्ता को ओवरराइड करते हैं।
स्विफ्ट प्रोग्रामिंग गाइड के "Initialization: Designated Initializers and Convenience Initializers" अनुभाग से:

If the initializer you are overriding is a convenience initializer, your override must call another designated initializer from its own subclass, as per the rules described above in Initializer Chaining.

आपके मामले में, आप शायद init(window: NSWindow!) ओवरराइड और वहाँ से सुपर समकक्ष फोन करना चाहिए।

+0

आपकी व्याख्या के लिए धन्यवाद, मुझे आश्चर्य है कि मैं एनआईबी फाइल से एनएसविंडो ऑब्जेक्ट कैसे बना सकता हूं? –

+0

मेरा मतलब है कि विंडो ऑब्जेक्ट को nib फ़ाइल से बनाया जाना चाहिए, है ना? और मैं खिड़की को निब फ़ाइल से कैसे बना सकता हूं? –

+0

यदि आपके पास अपने विंडो नियंत्रक के लिए एक समर्पित xib है, तो आप फ़ाइल स्वामी के पहचान निरीक्षक में अपने उप-वर्ग को "कस्टम क्लास" के रूप में सेट कर सकते हैं। ध्यान दें कि जब xib से विंडो नियंत्रक बनाया गया है, तो आपको initWithCindow के बजाय initWithCoder को ओवरराइड करना होगा यदि आप प्रारंभकर्ता में कुछ विशिष्ट करना चाहते हैं। –

5

आप लगभग वहां थे। ,

import Cocoa 

class MyWindowController: NSWindowController { 

    override convenience init() { 
     self.init(windowNibName: "<xib name>") 
    } 
} 

ध्यान दें कि आप self पर init(windowNibName:) बुला रहे हैं, क्योंकि init() एक सुविधा initialiser जा रहा है आप: आप वास्तव में एक तरह से एक सुविधा initialiser कि Obj सी कोड के बराबर है आप के लिए इस्तेमाल किया गया के रूप में init() ओवरराइड कर सकते हैं अभी भी superclass से सभी शुरुआती मालिकों का वारिस। documentation से:

Rule 1: A designated initializer must call a designated initializer from its immediate superclass.

Rule 2: A convenience initializer must call another initializer from the same class.

Rule 3: A convenience initializer must ultimately call a designated initializer.

इसके अलावा, जैसा कि ऊपर उल्लेख @weichsel के रूप में, आप NSWindowController के अपने उपवर्ग को File's Owner के वर्ग सेट करना (उपरोक्त उदाहरण में, कि हो सकता है MyWindowController) और तो इसकी window कनेक्ट खिड़की के साथ आउटलेट।

कहा जा रहा है कि, मुझे यकीन नहीं है कि संकलक override कीवर्ड जोड़ने के लिए क्यों पूछ रहा है। हालांकि NSWindowControllerNSResponder का एक उपवर्ग है, जो एक init() को परिभाषित करता है, निम्नलिखित कोड मुद्दे के बिना संकलित भले ही यह एक बराबर वंशानुगत पदानुक्रम लागू करता है:

class A { 
    init() { } 
} 

class B: A { 
    init(Int) { 
     super.init() 
    } 
    convenience init(String) { 
     self.init(5) 
    } 
} 

class C: B { 
    convenience init() { 
     self.init("5") 
    } 
} 
+0

मुझे Xcode 7.3 में त्रुटि "प्रारंभकर्ता प्रारंभिक प्रारंभकर्ता से अपने सुपरक्लास से ओवरराइड नहीं करता है" त्रुटि प्राप्त करता है। 'ओवरराइड' कीवर्ड को हटाने से त्रुटि से छुटकारा पाता है। –

+1

@ निकोलसमिआरी, जाहिर है, इस पोस्ट को लिखा गया था क्योंकि उस पोस्ट को ऐप्पल द्वारा संबोधित किया गया था। उस पर ध्यान देने के लिए धन्यवाद! क्या बदल गया है कि अब हमें अज्ञात मानकों को स्पष्ट रूप से चिह्नित करना है ('init (int) 'के बजाय, अब हम' init (_: int) 'लिखते हैं। – milos

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