swift - स्विफ्ट 5.0: 'withUnsafeBytes' को हटा दिया गया है: `withUnsafeBytes<R>(…) का उपयोग करें




deprecated unsafe-pointers (2)

Xcode 10.2 पर, स्विफ्ट 5, $0.load(as:) का उपयोग करते हुए $0.load(as:) ने मेरे लिए काम नहीं किया, जब दोनों सूचक से पढ़ रहे थे या इसे लिख रहे थे।

इसके बजाय, $0.baseAddress?.assumingMemoryBound(to:) का उपयोग करके $0.baseAddress?.assumingMemoryBound(to:) अच्छी तरह से काम करने लगता है।

पॉइंटर बफर से उदाहरण पढ़ना (कोड प्रश्न से संबंधित नहीं है):

var reachability: SCNetworkReachability?
data.withUnsafeBytes { ptr in
    guard let bytes = ptr.baseAddress?.assumingMemoryBound(to: Int8.self) else {
        return
    }
    reachability = SCNetworkReachabilityCreateWithName(nil, bytes)
}

बफ़र पॉइंटर के लिए उदाहरण लेखन (कोड प्रश्न से संबंधित नहीं है):

try outputData.withUnsafeMutableBytes { (outputBytes: UnsafeMutableRawBufferPointer) in
    let status = CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2),
                                      passphrase,
                                      passphrase.utf8.count,
                                      salt,
                                      salt.utf8.count,
                                      CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA1),
                                      rounds,
                                      outputBytes.baseAddress?.assumingMemoryBound(to: UInt8.self),
                                              kCCKeySizeAES256)
    guard status == kCCSuccess else {
        throw Error.keyDerivationError
    }
}

प्रश्न से कोड इस तरह दिखेगा:

let value = data.withUnsafeBytes { 
    $0.baseAddress?.assumingMemoryBound(to: UInt32.self)
}

ऐसे मामलों में जहां 'withUnsafeBytes' is deprecated: use withUnsafeBytes<R>(…) चेतावनी का उपयोग जारी रहता है, ऐसा लगता है कि कंपाइलर भ्रमित हो सकता है जब क्लोजर में केवल एक ही लाइन होती है । क्लोजर बनाने से दो या दो से अधिक लाइनें अस्पष्टता को दूर कर सकती हैं।

मैंने पूर्व में आईडी बनाने के लिए स्विफ्ट 4.2 में इस कोड का उपयोग किया था:

public static func generateId() throws -> UInt32 {
    let data: Data = try random(bytes: 4)
    let value: UInt32 = data.withUnsafeBytes { $0.pointee } // deprecated warning!
    return value // + some other stuff 
}

withUnsafeBytes स्विफ्ट 5.0 पर withUnsafeBytes है। इसे कैसे हल किया जा सकता है?


स्विफ्ट 5 में Data साथ withUnsafeBytes() विधि कॉल को एक UnsafeRawBufferPointer ( UnsafeRawBufferPointer ) UnsafeRawBufferPointer साथ बंद कर UnsafeRawBufferPointer , और आप कच्ची मेमोरी से मान load() कर सकते हैं:

let value = data.withUnsafeBytes { $0.load(as: UInt32.self) }

(तुलना करें कि डेटा का उपयोग कैसे करें। अच्छी तरह से परिभाषित तरीके से डेटा का उपयोग करें । स्विफ्ट फोरम में)। ध्यान दें कि इसके लिए स्मृति को 4-बाइट सीमा पर संरेखित करना आवश्यक है। विकल्पों के लिए डेटा से / के लिए गोल यात्रा स्विफ्ट नंबर प्रकार देखें।

ध्यान दें कि स्विफ्ट 4.2 के रूप में आप नए Random एपीआई का उपयोग करके केवल 32-बिट पूर्णांक बना सकते हैं:

let randomId = UInt32.random(in: .min ... .max)




unsafe-pointers