4

I'm working with Swift 3.

I would like to have this C syntax :

int myVar;
int *pointer = &myVar;

So modifying pointer or myVar does the same exact same thing. Also I don't know if it makes any difference, but in my case myVar is an array containing elements of a class and pointer is a pointer to one element of this array.

asked Sep 13, 2017 at 18:45
3
  • Possible duplicate of How to do "Deep Copy" in Swift? Commented Sep 13, 2017 at 18:47
  • Have you tried it? In what way does var selectedRow = rows[0] not do what you want? (From your description, it seems to me that you don't want a copy at all, just a shared pointer.) Commented Sep 13, 2017 at 18:49
  • It creates a copy of rows[0] but the two variables are different, when I modify selectedRow it doesn't affect rows[0] at all. And yes I want a shared pointer. Commented Sep 13, 2017 at 18:51

4 Answers 4

4

The & also exists in Swift but can only be used as part of a parameter list (e.g. init, func, closure).

var i = 5
let ptr = UnsafeMutablePointer(&i)
print(ptr.pointee) // 5
// or
let ptr = UnsafeMutablePointer<Int>.allocate(capacity: 1)
ptr.initialize(to: 5)
// or with a closure
let ptr: UnsafePointer = { 0ドル }(&i)
answered Sep 13, 2017 at 20:43
Sign up to request clarification or add additional context in comments.

Comments

2

(Assuming I understand what you're asking for....)

Try the following code in a playground. It should print "99" three times.

class Row {
 var rowNumber = 0
}
var rows = [Row]()
let testRow = Row()
testRow.rowNumber = 1
rows.append(testRow)
let selectedRow = rows[0]
selectedRow.rowNumber = 99
print(testRow.rowNumber)
print(selectedRow.rowNumber)
print(rows[0].rowNumber)

By default, there's no copying of objects as part of an assignment statement. If it were a struct, that would be different.


Adding a bit for completeness:

If you want a similar effect with scalar values instead of objects, Swift supplies various types of wrappers.

let intPointer = UnsafeMutablePointer<Int>.allocate(capacity: 8) // Should be 1, not 8 according to comment re: docs
let other = intPointer
other.pointee = 34
print(intPointer.pointee)

(Warning: I haven't used these wrappers for anything except experimenting in a playground. Don't trust it without doing some research.)

answered Sep 13, 2017 at 19:05

4 Comments

Okay, I'm missing something here. I thought my code didn't work because this syntax wasn't correct but I tried your code in a playground and it works fine, so my code works too, I must have something wrong elsewhere. Now why this works with a class but not with variables ? for example var myVar = 5, var otherVar = myVar and otherVar = 5 doesn't change myVar value ?
The difference is that objects are referenced through pointers. So, in my case, I have one actual object and three variables containing the one value that points to it. In your myVar example, you're changing the actual variable contents; there's no independent object that they both reference. (It would be the same as me typing let selectedRow = Row() and expecting its changes to be reflected in testRow. People sometimes try that, but it never works. :) )
I'm pretty sure it should be .allocate(capacity: 1). Doc for the parameter: The amount of memory to allocate, counted in instances of Pointee.
Thanks @nyg. It's definitely not something I've looked at for real use.
1

Same example as @Phillip. But I used struct. In this example rows[0] won't change:

struct Row {
 var rowNumber = 0
}
var rows = [Row]()
var testRow = Row()
testRow.rowNumber = 1
rows.append(testRow)
var selectedRow = rows[0]
selectedRow.rowNumber = 99
print(testRow.rowNumber) // prints 1
print(selectedRow.rowNumber) // prints 99
print(rows[0].rowNumber) // prints 1
answered Sep 13, 2017 at 19:11

Comments

0

There are no C style pointers (Unsafe Pointer) as the question asks however objects are shared by reference and structures are by value:

Swift assign, pass and return a value by reference for reference type and by copy for Value Type

structures are always copied when they are passed around in your code, but classes are passed by reference.

For example

How to have pointers/ references to objects

class Song {
 
 init(title: String, image: String, file: String, volume: Float, queuePlayer: AVQueuePlayer, playerLooper: AVPlayerLooper?) {
 self.title = title
 self.image = image
 ...
 }
 var title: String
 var image: String
 ...
}
var aSong = Song(title: "", image: "", ...)
var arrOfSongReferences: [Song] = [Song]()
arrOfSongReferences.append(aSong)
var ptrToASong: Song = aSong
aSong = nil
// Due to Swift garbage collection ARC (Automatic Reference Counting), we still have references to the original aSong object so it won't be deleted

If data is struct you cannot do this

struct Song {
 var title: String
 var image: String
 ...
}
var aSong: Song = Song(title: "", image: "", ...)
var copyOfASong: Song = aSong

Method

You can also pass by reference into a function

// this would be inside a class, perhaps Player. It doesn't have to be a static btw
static func playSound(_ sound: inout Song, volume: Float = 0.0) {
 if (sound.playerLooper == nil) {
 ...
 }
}
// usage
Player.playSound(sound: &aSong)
answered Dec 20, 2021 at 0:48

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.