[swift-users] Memory management without ARC?

Matthias Zenger matthias at objecthub.net
Sat Jan 30 09:17:17 CST 2016


Hi everyone,

I'm currently writing a Scheme interpreter in Swift. My original plan was
to use Swift's memory management to handle objects in Scheme.
Unfortunately, Scheme's data structures are inherently cyclic and I'm
struggling to find a good approach to manage memory via ARC.

An example that highlights the problem are arrays that contain elements
that refer to the array itself. In Scheme, such arrays can be easily
created like this:

  (define vec (vector 1 2 3))
  (vector-set! vec 1 vec)

Vector vec now refers to itself via index 1.

For representing a Scheme array, my interpreter simply uses an object that
wraps a Swift array. The array elements point at Scheme objects. So, they
could point at the array itself. Since I don't want to loose objects that
are linked off the array only, I need to use strong references in the
array. Obviously, this creates a serious memory leak. Here's some code
illustrating the design and the construction of vec:

  enum SchemeValue {
    case Nil
    case Num(Int)
    indirect case Cons(SchemeValue, SchemeValue)
    case Vector(WrappedArray<SchemeValue>)
  }

  class WrappedArray<T> {
    var array: [T]
    init(_ elem: T...) {
      self.array = elem
    }
  }

  let wa = WrappedArray<SchemeValue>(.Num(1), .Num(2), .Num(3))
  let vec = SchemeValue.Vector(wa)
  wa.array[1] = vec

I haven't found a good way to address the issue. What I would ideally need
is manual access to retain/release functions. I would also be willing to
write my own memory manager for such objects, but also this seems to be
impossible in Swift. As a workaround, I currently built a mark/sweep
garbage collector for all Scheme objects I allocate (by keeping them all in
a weak object pool — also hand-written because it doesn't exist in Swift).
But I consider this application-specific garbage collector that runs on top
of ARC a huge heck.

So, my question is: What are Swift programmers supposed to do if they are
dealing with inherently cyclic data structures that cannot be broken up via
weak references? It almost seems like there's some memory management
functionality missing in Swift that makes this possible.

== Matthias
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20160130/65da8df9/attachment.html>


More information about the swift-users mailing list