2015-09-12 13 views
20

काम नहीं कर रहा मैं बहुत की तरह प्रोटोकॉल एक्सटेंशन का उपयोग कर कुछ UITextFieldDelegate के तरीकों पर एक डिफ़ॉल्ट व्यवहार को जोड़ने के लिए कोशिश कर रहा हूँ UITextFieldDelegate प्रोटोकॉल विस्तार:तेज 2.0 -

extension ViewController: UITextFieldDelegate { 
    // Works if I uncommented this so I know delegates are properly set 
// func textFieldShouldReturn(textField: UITextField) -> Bool { 
//  textField.resignFirstResponder() 
//  return true 
// } 
} 

extension UITextFieldDelegate { 
    func textFieldShouldReturn(textField: UITextField) -> Bool { 
     textField.resignFirstResponder() 

     return true 
    } 
} 

आप अनुमान लगा सकते हैं, कीबोर्ड कभी नहीं खारिज। मैं वास्तव में नहीं देख सकता कि यहां समस्या कहां है। क्या यह एक भाषा सीमा है? क्या किसी ने पहले से ही सफलता कर रही है?

संपादित करें:

रूप @Logan सुझाव दिया, डिफ़ॉल्ट प्रोटोकॉल की विधि कार्यान्वयन @objc के रूप में चिह्नित प्रोटोकॉल के साथ काम नहीं करता। हालांकि, UITextFieldDelegate निम्नलिखित हस्ताक्षर NSObjectProtocol के लिए public protocol UITextFieldDelegate : NSObjectProtocol {...}

मैंने परीक्षण डिफ़ॉल्ट कार्यान्वयन है और यह ठीक काम करता है लगता है:

protocol Toto: NSObjectProtocol { 
    func randomInt() -> Int 
} 

extension Toto { 
    func randomInt() -> Int { 
     return 0 
    } 
} 

class Tata: NSObject, Toto {} 

let int = Tata().randomInt() // returns 0 

उत्तर

8

मैं 100% सकारात्मक नहीं किया जा सकता है, लेकिन यहाँ है कि मैं क्या विश्वास करते हैं क्या हो रहा है :

प्रोटोकॉल एक्सटेंशन ObjC से उपलब्ध नहीं हैं। चूंकि UITextFieldDelegateObjC प्रोटोकॉल है, यह ObjC प्रेषण पर निर्भर है। जहां तक ​​कंपाइलर का संबंध है, आपके डिफ़ॉल्ट कार्यान्वयन में विधियां पहुंच योग्य नहीं हैं, भले ही वे मौजूद हों।

स्पष्टीकरण के लिए, हम इन प्रोटोकॉल का विस्तार कर सकते हैं यदि यह वास्तव में एक विस्तार और व्यवहार जोड़ता है। यह व्यवहार केवल स्विफ्ट में ही पहुंच योग्य होगा और किसी भी तरह से समस्याग्रस्त नहीं होना चाहिए।

समस्या डिफ़ॉल्ट कार्यान्वयन ObjC पहुंच योग्य नहीं है।

यहाँ एक कस्टम संस्करण की एक त्वरित उदाहरण है:

@objc protocol Test : class { 
    func someFunc() -> String 
} 

extension Test { 
    func someFunc() -> String { 
     return "" 
    } 
} 

// Fails here 'candidate is not @objc but protocol requires it` 
class Hi : NSObject, Test { 

} 

Xcode पता चलता है @objc जोड़कर लेकिन यह जब तक आप @objc @objc @objc Hi : ...

मिल नीचे हमारी बातचीत के आधार पर फिर से इस अधिक से अधिक सुझाव रखेंगे, मैंने बनाया यह काम करता प्रतीत होता है। मैं पूरी तरह से व्याख्या नहीं कर सकते क्यों अभी तक:

@objc public protocol Toto: UITextFieldDelegate { 
    optional func randomInt() -> Int 
} 

extension Toto { 
    func randomInt() -> Int { 
     return 0 
    } 
    func textFieldShouldReturn(textField: UITextField) -> Bool { 
     return false 
    } 
} 

class Tata: NSObject, Toto { 
} 

ठीक है, मुझे लगता है कि मैं एक अलग समस्या पर विचार कर रहा हूँ, और जब यह संकलित, यह काम नहीं करेगा, और इस मुद्दे को गतिशील प्रेषण है। यदि आप अपनी विधि w/@objc, या dynamic को जोड़ने का प्रयास करते हैं, तो संकलक आपको चेतावनी देगा कि आप कक्षाओं को छोड़कर इस तरह से प्रेषित नहीं कर सकते हैं। चूंकि प्रोटोकॉल अपवाद इस बात के अनुरूप नहीं है, जब ओबीजेसी संदेश भेजने को भेजता है, तो यह आपके एक्सटेंशन में कार्यान्वयन नहीं ढूंढ सकता है।

स्विफ्ट के बाद से लगातार अपडेट कर रहा है, यहाँ जब इस उत्तर लागू था है:

स्विफ्ट 2.0 Xcode 7 जीएम

+0

'UITextFieldDelegate' हस्ताक्षर 'सार्वजनिक प्रोटोकॉल UITextFieldDelegate: NSObjectProtocol {...}' जैसा दिखता है। मैंने प्रोटोकॉल के लिए प्रोटोकॉल एक्सटेंशन का परीक्षण किया है जो 'NSObjectProtocol' लागू करता है और यह समस्याग्रस्त नहीं लगता है। इसके अलावा, अगर मैं 'obj' प्रोटोकॉल का विस्तार करने की कोशिश करता हूं तो संकलक मुझे चेतावनी नहीं दे सकता है? – Yaman

+0

@ यमन - हम सभी जानते हैं कि कंपाइलर चेतावनियां स्विफ्ट में और कभी-कभी इसके अस्पष्ट नहीं हैं। यदि आप कम से कम मेरे सिस्टम पर 'अनुरूप नहीं है' से परे देखते हैं, तो मुझे '@ objc' चेतावनी भी मिलती है जो '@ objc' जोड़ती रहती है लेकिन समस्या को कभी हल नहीं करती है। मुद्दा किसी ओबीजेसी प्रोटोकॉल को विस्तारित नहीं कर रहा है, किसी भी भ्रम के बारे में खेद है। मुद्दा डिफ़ॉल्ट व्यवहार बना रहा है जो ओबीजेसी पहुंच पर निर्भर है। एक ओबीजेसी प्रोटोकॉल में नई विधियों को विस्तार और जोड़ना जो स्विफ्ट में केवल पहुंच योग्य है ठीक है। डिफ़ॉल्ट कार्यान्वयन को जोड़ना जो ओबीजेसी सुलभ होना चाहिए, इस मुद्दे का कारण बनता है। – Logan

+0

इन परिशुद्धता के लिए धन्यवाद। मैंने प्रोटोकॉल के लिए डिफ़ॉल्ट कार्यान्वयन का भी परीक्षण किया है जो 'NSObjectProtocol' को लागू करता है और यह भी काम करता है। क्या 'NSObjectProtocol' घोषित करना' @ objc' चिह्न के बराबर है? हो सकता है कि 'UITextFieldDelegate' प्रोटोकॉल को '@ objc' के रूप में चिह्नित किया गया हो लेकिन मेरा कस्टम प्रोटोकॉल जो 'NSObjectProtocol' को लागू करता है' नहीं है? – Yaman

3

अच्छा चर्चा यहाँ है, और वास्तव में क्या मैं इस बिंदु पर शक कर रहा हूँ के रूप में अच्छी तरह से। एक और बात यहां उल्लेखित नहीं है - शायद यह ओबीजे-सी के व्यापक मुद्दे के कारण हो सकता है जो स्विफ्ट प्रोटोकॉल एक्सटेंशन कार्यान्वयन तक पहुंचने में सक्षम नहीं है।

उदाहरण के लिए, निम्न कोड: इस प्रकार हैं (अपनी पोस्ट के समान प्रोटोकॉल एक्सटेंशन का उपयोग

@interface MyViewController (SWIFT_EXTENSION(MyApp)) <UITextFieldDelegate> 
- (void)textFieldDidBeginEditing:(UITextField * __nonnull)textField; 
@end 

हालांकि,:

class MyViewController: UIViewController, MyTextFieldDelegateProtocol { 
    @IBOutlet weak var textField: UITextField! 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     textField.delegate = self 
    } 
} 
extension MyViewController: UITextFieldDelegate { 
    func textFieldDidBeginEditing(textField: UITextField) { 
     print("shouldChangeCharactersInRange called") 
    } 
} 

विस्तार के लिए स्विफ्ट उत्पन्न शीर्षक में निम्नलिखित तैयार करेगा):

class MyViewController: UIViewController, MyTextFieldDelegateProtocol { 
    // ... 
} 

@objc protocol MyTextFieldDelegateProtocol: UITextFieldDelegate {} 
extension MyTextFieldDelegateProtocol { 
    func textFieldDidBeginEditing(textField: UITextField) { 
     print("shouldChangeCharactersInRange called") 
    } 
} 

पी के लिए स्विफ्ट हेडर में निम्नलिखित उत्पन्न करता है rotocol:

SWIFT_PROTOCOL("_TtP8MyApp27MyTextFieldDelegateProtocol_") 
@protocol MyTextFieldDelegateProtocol <UITextFieldDelegate> 
@end 

कार्यान्वयन बिल्कुल दिखाई नहीं है, और इसलिए यह मतलब है प्रोटोकॉल विस्तार कार्यान्वयन Obj सी से समर्थित नहीं हैं लगता है। मैंने यह भी पाया कि किसी ने यहां सवाल पूछा है (हालांकि अभी तक कोई जवाब नहीं है): Can Swift Method Defined on Extensions on Protocols Accessed in Objective-c

दुर्भाग्य से, मुझे अभी तक इस सीमा के बारे में कोई आधिकारिक सेब दस्तावेज़ नहीं मिला है।