DCDC DCDC - 3 months ago 27
iOS Question

Declaring fixed-size NSData() object

I want to create fixed-size NSData object to possibly improve performance.

var data = NSData(bytes: [], length: 18)


In Swift playground I see the result

<a074740f 01000000 00bf740f 01000000 babc>


Is it correct? Shouldn't they all be 0?

Also, is it a good practice to instantiate a NSData object with fixed-size when I'm sure it's going be that long?

It's worth to say that I need to "empty" this object after each time it's used, I read that the best way to accoplish that is just to assign a new object

self.data = NSData()


What if I use here the first snippet of code with fixed-length? I'll get these random values instead of empty NSData with fixed size

EDIT:

To provide more details about what I am actually trying to achieve:

I read data from BLE, to synchronize them I use timer that reads the current value form variable and clears that variable value afterwards.

First of all, I'd like to declare fixed-size NSData variable, because i suppose it will hone the entire performance

Second, I'd like to clear variable value after being used

This is how I do it on String to see them printed in console, by default i want to store values as NSData and pass to another class

class DataSynchronizer
{
var timer:NSTimer
var tag1:NSData = NSData()
var tag2:NSData = NSData()
var gpsData:CLLocation?
var timeInterval:Double


init(frequency:Double)
{
self.timer = NSTimer()
self.timeInterval = 1 / frequency

}

func scheduledTimerWithTimeInterval(){
// Scheduling timer to Call the function **Countdown** with the interval of 1 seconds
self.timer = NSTimer.scheduledTimerWithTimeInterval(self.timeInterval, target: self, selector: #selector(DataSynchronizer.syncValues), userInfo: nil, repeats: true)
}

func stopTimer()
{
self.timer.invalidate()
}


@objc func syncValues()
{
print(self.tag1)
self.tag1 = NSData()
print(self.tag2)
self.tag2 = NSData()
print("\n")
}
}


tag1 and tag2 values are modified from another class that handles BLE

func peripheral(peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?) {
if self.updateStarted == false{
self.updateStarted = true
}

let firstTagIdentifier = self.tagsIds[0]

if "\(peripheral.identifier)" == firstTagIdentifier
{

self.peripheralCounter = self.peripheralCounter + 1

let date = NSDate()
if characteristic.value?.length == 18
{

synchronizer.tag1 = characteristic.value! //synchronizer is a DataSynchronizer instance
}

Answer
var data = NSData(bytes: [], length: 18)

causes undefined behavior: It reads 18 bytes from an empty array.

let data = NSMutableData(capacity: 18)!

would create an (empty) data object with the capacity to hold 18 bytes, and

let data = NSMutableData()
data.length = 18

would create a data object with 18 zero bytes. You can empty the contents with

data.length = 0

But: With

synchronizer.tag1 = characteristic.value!

the value stored in synchronizer.tag1 is overwritten, which means that the previously assigned data object is released. It does therefore not matter if you assigned a fixed-size data object before or not. It is also no performance improvement because you got the NSData object from characteristic.value.

If you want to "clear" the data in the synchronizer class then define the tags as optional variables:

var tag1: NSData?
var tag2: NSData?

Now you can assign data, and get rid of it by assigning nil again:

tag1 = nil
tag2 = nil