简体   繁体   中英

Converting Objective-C malloc to Swift

I am working on a project that was written in Objective-C and needs to be updated to Swift. We use a C file for transferring data.

Here is the code I was given in Objective-C:

- (NSData *)prepareEndPacket {
    UInt8 *buff_data;
    buff_data = (uint8_t *)malloc(sizeof(uint8_t)*(PACKET_SIZE+5));
    // Call to C File
    PrepareEndPacket(buff_data);
    NSData *data_first = [NSData dataWithBytes:buff_data length:sizeof(uint8_t)*(PACKET_SIZE+5)];
    return data_first;
}

In the C .h file I have this for reference:

#define PACKET_SIZE     ((uint32_t)128)

I can not seem to find a good way of converting this to Swift. Any help would be appreciated.

malloc and free actually work fine in Swift; however, the UnsafeMutablePointer API is more "native". I'd probably use Data 's bytesNoCopy for better performance. If you want, you can use Data(bytes:count:) , but that will make a copy of the data (and then you need to make sure to deallocate the pointer after making the copy, or you'll leak memory, which is actually a problem in the Objective-C code above since it fails to free the buffer).

So, something like:

func prepareEndPacket() -> Data {
    let count = PACKET_SIZE + 5
    let buf = UnsafeMutablePointer<UInt8>.allocate(capacity: count)

    PrepareEndPacket(buf)

    return Data(bytesNoCopy: buf, count: count, deallocator: .custom { ptr, _ in
        ptr.deallocate()
    })
}

By using bytesNoCopy , the Data object returned is basically a wrapper around the original pointer, which will be freed by the deallocator when the Data object is destroyed.

Alternatively, you can create the Data object from scratch and get a pointer to its contents to pass to PrepareEndPacket() :

func prepareEndPacket() -> Data {
    var data = Data(count: PACKET_SIZE + 5)

    data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
        PrepareEndPacket(ptr)
    }

    return data
}

This is slightly less efficient, since the Data(count:) initializer will initialize all the Data 's bytes to zero (similar to using calloc instead of malloc ), but in many cases, that may not make enough of a difference to matter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM