दिलचस्प पोस्ट
किसी निर्माता की प्रारंभिक सूची से अपवाद पकड़ना जीसीसी एमिंगव का प्रयोग करके द्विआधारी ब्लॉब्स एम्बेड करना पेज ExecJS :: ProgramError पृष्ठों # होम में रेल? HTML नेस्टेड सूची बनाने का उचित तरीका है? मैं जावा के लिए एक अलग कंपाइलर संस्करण का उपयोग कैसे करूं? regex त्रुटि – दोहराने के लिए कुछ नहीं एकता में रायस्ट के साथ परतें और बिटमैस्क का उपयोग करना तारांकन चिह्न के रूप में पासवर्ड कैसे गूँज गया है एक अज्ञात वर्ग के निर्माता तक पहुंच मैं ToString () के साथ एक नल योग्य तारीख का समय कैसे प्रारूपित कर सकता हूँ? XML नामस्थानों के साथ XPath कैसे काम करता है? मेनूइटम शॉर्टकट को परिभाषित करना बैच में एक सूची को तोड़ने के लिए आम उपयोग वेबवेव onreceivedSslError के क्रियान्वयन पर Google Play से सुरक्षा अलर्ट से बचें कैसे CPU उपयोग सी # में प्राप्त करने के लिए?

कैसे स्वयं को अस्वास्थ्ययोग्य पॉइंटर <Void> प्रकार में तेजी से डाली जाए

"स्वयं" को तेजी से सी फंक्शन में पास करने की कोशिश करते हुए, निम्नलिखित कोड को कॉल करते समय:

var callbackStruct : AURenderCallbackStruct = AURenderCallbackStruct.init( inputProc: recordingCallback, inputProcRefCon: UnsafeMutablePointer<Void> ) 

यहां एक असुरक्षितकुंजनीय सूचक प्रकार को "स्व" डालने का आदर्श तरीका क्या है?

वेब के समाधान से एकत्रित समाधान "कैसे स्वयं को अस्वास्थ्ययोग्य पॉइंटर <Void> प्रकार में तेजी से डाली जाए"

ऑब्जेक्ट पॉइंटर (अर्थात् एक संदर्भ प्रकार का उदाहरण) को UnsafePointer<Void> परिवर्तित किया जा सकता है UnsafePointer<Void> (स्विफ्ट मैपिंग का const void * UnsafeRawPointer const void * , UnsafeRawPointer इन स्विफ्ट 3) और वापस। उद्देश्य-सी में आप लिखेंगे

 void *voidPtr = (__bridge void*)self; // MyType *mySelf = (__bridge MyType *)voidPtr; 

(देखें इन चीजों के सटीक अर्थ के लिए क्लैंक एआरसी दस्तावेज में 3.2.4 बछेड़ा डाली गई।)

उस उद्देश्य के लिए स्विफ्ट का एक Unmanaged प्रकार है यह थोड़े बोझिल है क्योंकि यह COpaquePointer UnsafePointer<Void> बजाय COpaquePointer साथ काम करता है यहां दो सहायक विधियां हैं (उद्देश्य- C __bridge कास्ट के नाम पर):

 func bridge<T : AnyObject>(obj : T) -> UnsafePointer<Void> { return UnsafePointer(Unmanaged.passUnretained(obj).toOpaque()) // return unsafeAddressOf(obj) // *** } func bridge<T : AnyObject>(ptr : UnsafePointer<Void>) -> T { return Unmanaged<T>.fromOpaque(COpaquePointer(ptr)).takeUnretainedValue() // return unsafeBitCast(ptr, T.self) // *** } 

"जटिल" अभिव्यक्ति केवल स्विवर्स सख्त प्रकार सिस्टम को पूरा करने के लिए आवश्यक है संकलित कोड में यह केवल पॉइंटर्स के बीच एक कास्ट है (यह कम से कम लिखा जा सकता है जैसा कि *** टिप्पणियों में संकेत दिया गया है यदि आप "असुरक्षित" विधियों का उपयोग करने के लिए तैयार हैं, लेकिन संकलित कोड समान है।)

इस सहायक विधियों का उपयोग करके आप self को C फ़ंक्शन के रूप में पास कर सकते हैं

  let voidPtr = bridge(self) 

(या UnsafeMutablePointer<Void>(bridge(self)) यदि सी फ़ंक्शन को UnsafeMutablePointer<Void>(bridge(self)) आवश्यकता होती है), और इसे किसी ऑब्जेक्ट पॉइंटर पर वापस रूपांतरित कर देता है – उदा। एक कॉलबैक फ़ंक्शन में – जैसा कि

  let mySelf : MyType = bridge(voidPtr) 

स्वामित्व का कोई स्थान नहीं लेता है, इसलिए आपको सुनिश्चित करना चाहिए कि जब तक शून्य सूचक उपयोग किया जाता है तब तक self मौजूद नहीं है।


और पूर्णता के लिए, __bridge_retained के स्विफ्ट समकक्ष और उद्देश्य-सी से __bridge_transfer होगा

 func bridgeRetained<T : AnyObject>(obj : T) -> UnsafePointer<Void> { return UnsafePointer(Unmanaged.passRetained(obj).toOpaque()) } func bridgeTransfer<T : AnyObject>(ptr : UnsafePointer<Void>) -> T { return Unmanaged<T>.fromOpaque(COpaquePointer(ptr)).takeRetainedValue() } 

bridgeRetained() ऑब्जेक्ट पॉइंटर को शून्य पॉइंटर में bridgeRetained() और ऑब्जेक्ट को बरकरार रखता है। bridgeTransfer() शून्य सूचक को एक ऑब्जेक्ट पॉइंटर पर वापस ले जाता है और बनाए रखता है।

एक फायदा यह है कि ऑब्जेक्ट को कॉल के बीच हटाए नहीं जा सकता क्योंकि एक मजबूत संदर्भ आयोजित किया जाता है। इसका नुकसान यह है कि कॉल ठीक से संतुलित होना चाहिए, और यह आसानी से चक्र बनाए रखने का कारण हो सकता है


स्विफ्ट 3 (Xcode 8) के लिए अपडेट:

 func bridge<T : AnyObject>(obj : T) -> UnsafeRawPointer { return UnsafeRawPointer(Unmanaged.passUnretained(obj).toOpaque()) } func bridge<T : AnyObject>(ptr : UnsafeRawPointer) -> T { return Unmanaged<T>.fromOpaque(ptr).takeUnretainedValue() } func bridgeRetained<T : AnyObject>(obj : T) -> UnsafeRawPointer { return UnsafeRawPointer(Unmanaged.passRetained(obj).toOpaque()) } func bridgeTransfer<T : AnyObject>(ptr : UnsafeRawPointer) -> T { return Unmanaged<T>.fromOpaque(ptr).takeRetainedValue() } 

"असुरक्षित संकेतक" में प्रासंगिक परिवर्तनों का वर्णन किया गया है

  • असुरक्षित सूचक का उपयोग करने के लिए एसई -10017 बदलें अप्रबंधित
  • एसई -1107 असुरक्षितरापीक एपीआई

मुझे ऐसा लगता है कि यह वही है जो withUnsafeMutablePointer के लिए है – एक withUnsafeMutablePointer स्विफ्ट पॉइंटर को सी पॉइंटर में परिवर्तित करने के लिए। तो संभवतः आप ऐसा कर सकते हैं (मैंने इसे करने की कोशिश नहीं की है, लेकिन मैंने परीक्षण किए गए कोड को सुरक्षित तरीके से काम किया है):

 var mself = self withUnsafeMutablePointer(&mself) { v in let v2 = UnsafeMutablePointer<Void>(v) myStruct.inputProcRefCon = v2 } 
 func bridge<T : AnyObject>(obj : T) -> UnsafePointer<Void> { return UnsafePointer(Unmanaged.passUnretained(obj).toOpaque()) } func bridge<T : AnyObject>(ptr : UnsafePointer<Void>) -> T { return Unmanaged<T>.fromOpaque(ptr).takeUnretainedValue() } func bridgeRetained<T : AnyObject>(obj : T) -> UnsafePointer<Void> { return UnsafePointer( Unmanaged.passRetained(obj).toOpaque())} func bridgeTransfer<T : AnyObject>(ptr : UnsafePointer<Void>) -> T { return Unmanaged<T>.fromOpaque(ptr).takeRetainedValue()} 

यह उत्तर मार्टिन आर के उत्तर के रूप में कॉलबैक के लिए विषय-विशिष्ट नहीं दिखता, लेकिन इसका उपयोग हो सकता है …

आप आमतौर पर किसी भी प्रकार के मूल्य को असुरक्षित शून्य सूचक & ऑपरेटर का उपयोग कर सकते हैं:

 func baz(p: UnsafeMutablePointer<Void>) -> String { return "\(p)" } var num = 5 print(baz(&num)) 

हालांकि, self को पारित करने के लिए आपको ऐसे संदर्भ में ऐसा करने की ज़रूरत होगी जहां self अस्थिर है इसका मतलब है कि आपको इसे किसी प्रकार की एक mutating विधि (या एक init ) में करने की आवश्यकता होगी, संदर्भ प्रकार नहीं:

 struct FooValue { mutating func bar() { print(baz(&self)) } } var myFooValue = FooValue() myFooValue.bar() 

यदि आप किसी संदर्भ प्रकार का उपयोग करना चाहते हैं, तो आपको संदर्भ के एक स्थानीय प्रतिलिपि बनाने और उस पर एक संकेतक पास करने की आवश्यकता होगी:

 class FooReference { func bar() { var localSelf = self print(baz(&localSelf)) } } let myFooReference = FooReference() myFooReference.bar()