Click here to Skip to main content
13,144,309 members (35,372 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as


1 bookmarked
Posted 30 Jun 2014

Resolving Strong References Between Swift and Objective-C Classes - Using Unowned and Weak References from Swift to Objective-C Classes

, 30 Jun 2014
Rate this:
Please Sign up or sign in to vote.
How to resolve strong references between Swift and Objective-C classes - using unowned and weak references from Swift to Objective-C classes

My Swift and SpriteKit exploration continues. At the moment, I'm writing the collision handling code.

Rather than derive game objects from SKSpriteNode with each derived class containing the code for handling collisions with the other types of game objects, I'm following something akin to a Component-Entity model.

I have per-game-object handler classes of which an instance of each is stored in the actual SKSpriteNode's userData dictionary. In turn, each handler instance has a reference to the SKSpriteNode that references it. Given ARC is used, this is a classical strong-reference chain which will prevent memory from being freed. The usual solution to this in Objective-C is to have one of the references be weak. In Swift, there are two types of weak references: weak which is the same as in Objective-C and unowned (which I think is new). The difference is that an unowned reference can never be nil, i.e. it's optional whether a weak pointer references an object but an unowned pointer must always reference something. As such, the member variable is always defined using let and must be initialized, i.e., an init method is required.

The following code shows how I was intending to implement this. There is the strong reference from node.UserData to PhysicsActions and then the unowned reference back again from PhysicsActions.

class PhysicsActions
  unowned let node : SKSpriteNode

  init(associatedNode : SKSpriteNode)
    // Store really weak (unowned) reference
    self.node = associatedNode

  func onContact(other : PhysicsActions)
     // Do stuff with node

class func makeNode(imageNamed name: String) -> SKSpriteNode
  let node = SKSpriteNode(imageNamed: name)

  node.userData = NSMutableDictionary()
  // Store strong reference
  node.userData["action"] = makeActionFn(node)

  return node

However, when I went to use this code, it crashed within the onContact method when it attempted to use the node. Changing this, the reference type from unowned to weak fixed this, e.g.

weak let node : SKSpriteNode?

This verified that the rest of the code was ok so this seemed to look like another Swift/Objective-C interoperability issue. Firstly, I made a pure Swift example which is a simplified version from the The Swift Programming Language book.

class Foo
  var bar : Bar?

  func addBar(bar: Bar)
  { = bar

class Bar
  unowned let foo : Foo

  init(foo : Foo)
  { = foo

  func f()

var foo : Foo? = Foo()
var bar = Bar(foo: foo!)


which works and results in:

foo:C14XXXUnownedTest3Foo (has 1 child)

Ok, not a fundamental problem, but let's try having an unowned reference to an Objective-C class which is just like the real case as that's what SKSpriteNode is.


@interface Foo2 : NSObject



@implementation Foo2

  return [super init];



class Bar2
  unowned let foo2 : Foo2

  init(foo2 : Foo2)
    self.foo2 = foo2

  func f()

var foo2 = Foo2()
var bar2 = Bar2(foo2: foo2)


Which when foo2.f() is invoked results in:

0x100142420:  pushq  %rbp
0x100142421:  movq   %rsp, %rbp
0x100142424:  leaq   0x17597(%rip), %rax       ; "attempted to retain deallocated object"
0x10014242b:  movq   %rax, 0x348be(%rip)       ; gCRAnnotations + 8
0x100142432:  int3   
0x100142433:  nopw   %cs:(%rax,%rax)

Again, changing unowned let foo2 : Foo2 to weak var foo2 : Foo2? works.

I can't explain what the actual problem is but it looks like the enhanced weak reference support (unowned) only works with pure Swift classes. If you have cyclic references to Objective-C classes from Swift, then don't use unowned. In fact, writing the previous sentence led me to try the following:

let orig = Foo2()
unowned let other = orig


No cyclic references, just an ordinary reference counted instance of Foo2 (the Objective-C class) which is then assigned to an unowned reference. The final call to println will keep the instance around until the end. This crashes as per the previous example when the other variable is accessed. Changing the type assigned to orig from Foo2 (Objective-C) to Foo (Swift) make it work.

Therefore, it seems unowned should not be used to refer to Objective-C classes, just Swift classes.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Team Leader
United Kingdom United Kingdom
My day job is mostly working in C++ with a bit of C#. I write a fair amount of command line based tools and really wish they could have a GUI front-end to them hence why I spend my spare time working with WPF.

I started a blog few years back but didn't do a lot with it. I've started describing some of the interesting programming things I come across on it. Please take a look.

You may also be interested in...

Comments and Discussions

GeneralMy vote of 5 Pin
Volynsky Alex14-Dec-14 12:14
professionalVolynsky Alex14-Dec-14 12:14 
GeneralMy vote of 5 Pin
Volynsky Alex22-Nov-14 13:52
professionalVolynsky Alex22-Nov-14 13:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.170915.1 | Last Updated 30 Jun 2014
Article Copyright 2014 by PeteBarber
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid