How to Store a Reference to an Integer in Swift

How to store a reference to an integer in Swift

Unfortunately there is no reference type Integer or something like that in Swift so you have to make a Box-Type yourself.

For example a generic one:

class Reference<T> {
var value: T
init(_ value: T) { self.value = value }
}

How to get the reference of a value type in Swift?

There are several ways to get a reference. Kristopher's Box solution is one of the most flexible, and can be built as a custom box to handle problems like passing structs to ObjC.

Beyond that, the most obvious is passing inout parameters. This isn't precisely the same thing as a reference, but its behavior can be very similar, and definitely can be a part of high-performance code.

And moving down the stack there is UnsafePointer and its friends, using withUnsafePointer(to:) on general types, or .withUnsafeBufferPointer on array types.

But if you need a persistent reference type that can be stored in a property, you'll need a Box as Kristopher describes.

(Just to capture it for future readers since I hadn't remembered it, but MartinR pointed it out in a comment: as AnyObject can automatically box value types.)

Saving And Loading An Integer On Xcode Swift

If it isn't a lot of data, the strategy I use to save data, pass it between pages, and persist it between app runs is to store the value in NSUserDefaults.

Setting A Value: When you first get or when you change the data, store it in NSUserDefaults.

@IBAction func MoneyPress(sender: AnyObject) {
Money += 1
var MoneyNumberString:String = String(format: "Dollars:%i", Money)
self.DollarsLabel.text = (string: MoneyNumberString)
let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults() //This class variable needs to be defined every class where you set or fetch values from NSUserDefaults
defaults.setObject(MoneyNumberString, forKey: "money")
defaults.synchronize() //Call when you're done editing all defaults for the method.
}

Loading A Value: When you need to get the values, just grab it from NSUserDefaults.

@IBAction func loadButton(sender: UIButton) {
let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
var money = defaults.valueForKey("money") as? String
dollarLabel.text! = money
}

To remove the stored data, all you need to do is call the removeObjectForKey function for each key previously set.

let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
defaults.removeObjectForKey("money")
defaults.synchronize()

Helpful Source on NSUserDefaults:

NSUserDefulats Class Reference: Link here.

Is it possible to reference a variable with a string and an int?

This is an anti-pattern I call the Poor Man's Array. The better way to do this is to use a proper collection like an array instead of a bunch of variables that are secretly related. Done right, the code with an array will usually be a lot shorter and cleaner too.

Swift reference vs value with arrays and dictionaries

Swift arrays and dictionaries are value types. When you assign one that is in a variable to another variable, you are making a copy of the original.

So when you do this:

var ref = (dict[56]?.stringArray)!

ref is an entirely new copy of the array and not the one that is in the dictionary, so modifying it has no effect on the original copy in the dictionary.

If instead you had done:

dict[56]?.stringArray.append("2 line")

then you would have modified the copy that is in the dictionary.


Note: In reality, Swift doesn't make a copy of the array until you modify one of the copies. This is done behind the scenes to avoid unnecessary copying and to keep things quick. The copy logically happens immediately when you assign it, but you wouldn't notice the difference until you start modifying one of the copies, so Swift delays the copy until it matters.


Now consider this change to your code:

var ref = dict[56]!
print(ref.stringArray.count) // 1
ref.stringArray.append("2 line")

var anotherRef = dict[56]!
print(anotherRef.stringArray.count) // 2 this time!!!

Here, ref points to an instance of a class which is a reference type. In this case, both ref and anotherRef point to the same object, and thus you are modifying the array in the dictionary this time.

In Swift (iOS app), when do I need to use other integer types?

In the same way that Swift has other aspects underneath the covers such as pointers, these other numeric types are there for specific purposes. Some of these purposes are:

  • Integration with a C library. There may be specific C types that a C library requires and these types allow you to pass data to/from the libraries

  • Very large scientific datasets. Float (32-bit single precision floating point) allows you to keep twice the elements in memory in the same space as Double at some sacrifice to accuracy. Multi-day global environmental datasets from satellite sensors, astronomy datasets, etc. have huge space requirements.

  • Half-precision floating point requires half the storage and bandwidth of Float and can be pertinent for some graphics applications

  • Vector processing using the Accelerate library. Accelerate functions work with a variety of numeric types and 32-bit single precision accuracy may be acceptable for the task you wish to accomplish.

Swift, use string name to reference a variable

How about using a dictionary, [String : Int]?

This will allow you to achieve what you want - storing values for different keys.

For example, instead of using

var d1000 = 0
var d1289 = 0
var d1999 = 0

You could use

var dictionary: [String : Int] = [
"d1000" : 0,
"d1289" : 0,
"d1999" : 0
]

To store a value in the dictionary, just use

dictionary[key] = value
//for example, setting "d1289" to 1234
dictionary["d1289"] = 1234

and to get the value from the dictionary, use

let value = dictionary[key]
//for example, getting the value of "d1289"
let value = dictionary["d1289"]

So, you could use something like this

//initialize your dictionary
var myDictionary: [String : Int] = [:]

//your key initialization data
var deviceIDtype: Character = "d"
var deviceIDsection: String = "12"
var deviceID: String = "89"
var ref: String = ""

//your code
func devName(/*...*/){/*...*/}
ref = devName(/*...*/)

//set the key ref (fetched from devName) to 1234
myDictionary[ref] = 1234

Just as a side note, you could really clean some of your code

func devName(type: Character, section: String, id: String) -> String{      
return String(type) + section + id
}

//...

let key = devName(deviceIDtype, section: deviceIDsection, id: deviceID)
let value = 1234
myDictionary[key] = value


Related Topics



Leave a reply



Submit