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




deprecated unsafe-pointers (2)

मैंने पूर्व में आईडी बनाने के लिए स्विफ्ट 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 है। इसे कैसे हल किया जा सकता है?


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>(…) चेतावनी का उपयोग जारी रहता है, ऐसा लगता है कि कंपाइलर भ्रमित हो सकता है जब क्लोजर में केवल एक ही लाइन होती है । क्लोजर बनाने से दो या दो से अधिक लाइनें अस्पष्टता को दूर कर सकती हैं।


स्विफ्ट 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