क्या क्लास पर उद्देश्य-सी कोड स्विफ्ट एक्सटेंशन कह सकता है?


94

मैंने कुछ पोस्ट खोजे, मुझे लगता है कि मैं स्विफ्ट के तहत एक्सटेंशन नहीं लिख सकता, और इसे ऑब्जेक्टिव-सी कोड से कॉल कर सकता हूं, है ना?

@objc जैसी विशेषताएँ केवल विधियों, वर्ग, प्रोटोकॉल का समर्थन करती हैं?


1
आप इसे सिर्फ एक कोशिश क्यों नहीं करते?
HAS

7
ide ने त्रुटि की शिकायत की, लेकिन मैं एक निश्चित anwser प्राप्त करना चाहता हूं।
sprhawk

जवाबों:


84

आप एक स्विफ्ट एक्सटेंशन लिख सकते हैं और इसका उपयोग ऑब्जेक्टिव-सी कोड में कर सकते हैं। XCode 6.1.1 के साथ परीक्षण किया गया।

आपको बस इतना करना है:

  • स्विफ्ट में अपना एक्सटेंशन बनाएं (कोई @objcएनोटेशन नहीं )

  • #import "ProjectTarget-Swift.h" आपके उद्देश्य-सी वर्ग में (जहाँ "प्रोजेक्टटार्ग" XCode लक्ष्य का प्रतिनिधित्व करता है, स्विफ्ट एक्सटेंशन किससे जुड़ा है)

  • स्विफ्ट एक्सटेंशन से विधियों को कॉल करें

अद्यतन: जैसा कि @ रिजवान अहमद ने उल्लेख किया है, आपको @objcएनोटेशन जोड़ने की आवश्यकता है :

Swift 4.0.3 के अनुसार, यदि आप Objective C वर्ग फ़ाइलों में एक्सटेंशन का उपयोग करना चाहते हैं, तो @objc एनोटेशन की आवश्यकता है।


6
मैंने ठीक यही किया है, लेकिन यह अभी भी एक संकलन समय त्रुटि है। हममम। संपादित करें: मैंने "प्रोजेक्टटार्गेट-स्विफ्ट.एच" के बजाय अपने ब्रिजिंग हेडर को आयात किया । डेर।
जेसन रेनाल्डो

दोनों शीर्षासन कर रहे हैं। अंतर यह है कि एक ओब्जेक्ट में स्विफ्ट कोड का उपयोग करने के लिए है और दूसरा स्विफ्ट में ओजेसीसी कोड का उपयोग करने के लिए है। स्विफ्ट हैडर अदृश्य है। दूसरे को, आपके द्वारा प्रबंधित किया जाना चाहिए।
मार्स बार्डन

विलियम हू, देखें मैक्लोडीनज का जवाब!
सेबितुंग

39
Swift 4.0.3 के अनुसार, यदि आप Objective C वर्ग फ़ाइलों में एक्सटेंशन का उपयोग करना चाहते हैं, तो @objc एनोटेशन की आवश्यकता है।
रिजवान अहमद

68

मुझे पता चला कि स्विफ्ट 4.0 में मुझे @objcअपने एक्सटेंशन के सामने जोड़ना था कीवर्ड के स्विफ्ट एक्सटेंशन के तरीकों को जोड़ना था ताकि ओबजैक क्लास I का एक उदाहरण दिखाई दे।

संक्षेप में:

फ़ाइल कॉन्फ़िगरेशन सेटअप:

CustomClass.h
CustomClass.m
CustomClassExtension.swift

CustomClassExtension में:

@objc extension CustomClass
{
    func method1() 
    {
        ...
    }
}

मेरे AppDelegate.m में:

self.customClass = [[CustomClass alloc] init];
[self.customClass method1];

2
यदि कोई विधि जेनेरिक का उपयोग करती है, तो इसका उपयोग ऑब्जेक्टिव-सी द्वारा नहीं किया जा सकता है और आपको @nonobjcएनोटेशन जोड़ना होगा ।
थॉमस डब्ल्यू

सिर्फ एक सिद्दोटे, @objcMembers इस मामले में काम नहीं करता है। न जाने क्यों .. :-(
रौनक

46

यह समाधान स्विफ्ट 2.2 और स्विफ्ट 3 के लिए काम करता है । ध्यान दें कि ऑब्जेक्टिव-सी से केवल कक्षाओं के लिए एक्सटेंशन (स्ट्रक्चर या एनम के लिए नहीं) सुलभ होंगे।

import UIKit

extension UIColor {

    //Custom colours
    class func otherEventColor() -> UIColor {
        return UIColor(red:0.525, green:0.49, blue:0.929, alpha:1)
    }
}

फिर अपनी ObjC फ़ाइल में #import "ProductModuleName-Swift.h"

स्विफ्ट 4

extension UIColor {

    // As of Swift 4.0.3, the @objc annotation is needed if you want to use the extension in Objective-C files
    @objc
    class func otherEventColor() -> UIColor {
        return UIColor(red:0.525, green:0.49, blue:0.929, alpha:1)
    }
}

यह "YourProjectsNameHere ..." नहीं है, बल्कि "YourTargetsNameHere ...": लक्ष्य साझा करने के लिए, आपको इसे नाम पर लॉक करना होगा: dr2050.postach.io/post/…
Dan Rststark

1
@DanRosenstark आप सही हैं। मैं इसे "ProductModuleName-Swift.h" में बदल रहा हूं क्योंकि Apple सुझाव देता है: developer.apple.com/library/ios/documentation/Swift/Conceptual/…
Foti Dim

1
स्विफ्ट के लिए ठीक काम करता है 3.
विक्टर कुचेरा

क्या कोई कारण है कि आप कहते हैं publicकि जरूरत है? publicमेरे लिए संशोधक के बिना ठीक काम करता है । क्या हम यह मान रहे हैं कि विस्तार उसी परियोजना में नहीं है, बल्कि किसी अन्य परियोजना से आयात किया जा रहा है?
ली कांग

क्या मुझे ब्रिजिंग हेडर का उपयोग करने की आवश्यकता है?
jegadeesh

42

जैसा कि अन्य उत्तरों में कवर किया गया है, ज्यादातर मामलों में उत्पन्न स्विफ्ट हेडर का आयात करता है

इसका अपवाद तब होता है जब श्रेणी को एक ब्रिड्ड प्रकार पर परिभाषित किया जाता है (अर्थात एक्सटेंशन को परिभाषित किया गया है Stringऔर नहीं NSString)। इन श्रेणियों को स्वचालित रूप से उनके उद्देश्य-सी समकक्षों के लिए तैयार नहीं किया जाएगा। इसके आस-पास जाने के लिए, आपको या तो ऑब्जेक्टिव-सी टाइप का उपयोग करना होगा (और अपने स्विफ्ट कोड में रिटर्न वैल्यू डालनी होगी as String) या स्विफ्ट और ऑब्जेक्टिव-सी दोनों प्रकार के एक्सटेंशन को परिभाषित करना होगा।


2
उपरोक्त उत्तर में जोड़ते हुए, आपको अपना स्विफ्ट एक्सटेंशन सार्वजनिक करना चाहिए और इसके प्रकार को NSString उदा public extension NSString। क्या आपको संकलित समय पर एक अनसुलझी पहचानकर्ता या इसी तरह की त्रुटि मिलनी चाहिए, आप फिर से स्ट्रिंग जैसे उदाहरण के लिए फिर से कास्ट कर सकते हैं let sVal = self as Stringऔर फिर आवश्यक कोड पर कॉल करेंsVal
RunLoop

@RunLoop वास्तव में आपको सार्वजनिक की आवश्यकता नहीं है, यह कार्यक्षेत्र विनिर्देश के बिना काम करेगा। और यह (Obj-C के लिए निर्यात, मेरा मतलब है) स्ट्रिंग्स के लिए काम नहीं करता है, क्योंकि वे संरचनाएं हैं, कक्षाएं नहीं हैं और केवल स्विफ्ट से उपलब्ध हैं। तो, हाँ - आप NSString के लिए एक्सटेंशन लिख सकते हैं और कास्ट का उपयोग कर सकते हैं, या एक्सटेंशन लिख सकते हैं, जैसा mclaughlinjकि NSString वर्ग और स्ट्रिंग संरचना दोनों के लिए
एलेक्स Nazarsky

3

वस्तुनिष्ठ-ग फ़ाइल में "#import" ProductModuleName-Swift.h " हेडर आयात करें और स्विफ्ट फ़ाइल में अपने विस्तार का @objc infront जोड़ें । यह तेजी से 4.2 और स्विफ्ट 5 में ठीक काम करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.