[swift-users] Set size of byte array
KS Sreeram
ks at claylabs.com
Fri Aug 5 11:50:48 CDT 2016
> On 05-Aug-2016, at 4:02 PM, Brent Royal-Gordon <brent at architechies.com> wrote:
>
> I don't believe this is possible with an Array; the only way to work with uninitialized memory is with an UnsafeMutablePointer.
>
> The simplest solution is probably to load the data into an allocated chunk of memory with an UnsafeMutablePointer and then create an NSData object to keep track of its lifetime. The `init(bytesNoCopy:length:deallocator:)` initializer can be used to make sure it deallocates the memory correctly.
Thanks for the tip. This does mean I have to give up the niceties of arrays post initialization.
>
> If you don't *need* to use mutable pointers to fill the array, however, a custom SequenceType might be a better option. For instance, you could write a type like this which returns the data a byte at a time:
>
> struct MyDataSource: SequenceType, GeneratorType {
>
> Then you can write something like this:
>
> var source = MyDataSource(...)
> var array: [UInt8] = []
> array.reserveCapacity(source.initialCapacity)
> array.appendContentsOf(source)
>
> And, et voila, `array` is full of your bytes. From what I can tell, if the capacity is already there, the standard library effectively uses a loop as tight as any you could hope for:
>
> let base = buffer.firstElementAddress
>
> while (nextItem != nil) && count < capacity {
> (base + count).initialize(to: nextItem!)
> count += 1
> nextItem = stream.next()
> }
> buffer.count = count
>
> So I suspect a custom SequenceType will perform much better than you would first guess.
The code I’m working on essentially does serialization. It’s not really amenable to the inversion of control required for generators.
Best
KS Sreeram
More information about the swift-users
mailing list