Resolving strong references between Swift and Objective-C classes – Using unowned and weak references from Swift to Objective-C classes

Pete Barber from C#, C++, Windows & other ramblings

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 reference 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)
  {
    self.bar = bar
  }
}

class Bar
{
  unowned let foo : Foo
  init(foo : Foo)
  {
    self.foo = foo
  }

  func f()
  {
    println("foo:\(foo)")
  }
}

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

bar.f()

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.

Foo2.h

@interface Foo2 : NSObject
@end

Foo2.m

@implementation Foo2

-(id)init
{
  return [super init];
}

@end

main.swift

class Bar2
{
  unowned let foo2 : Foo2
  init(foo2 : Foo2)
  {
    self.foo2 = foo2
  }

  func f()
  {
    println("foo2:\(foo2)")
  }
}

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

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

libswift_stdlib_core.dylib`_swift_abortRetainUnowned:
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
println("other:\(other)")
println("orig:\(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.



Beware: Despite the docs SKNode userData is optional

Pete Barber from C#, C++, Windows & other ramblings

In the Swift documentation for SKNode the userData member (a dictionary) is defined as follows:

userData

A dictionary containing arbitrary data.

Declaration

SWIFT
var userData: NSMutableDictionary!

OBJECTIVE-C

@property(nonatomic, retain) NSMutableDictionary *userData

However, in Objective-C the userData member is initially nil. Given that this is the same class then it should also be in Swift and using it, e.g.

let node = SKSpriteNode(imageNamed: name)
node.userData["action"] = Action() // custom class

causes a crash:

fatal error: Can't unwrap Optional.None

This is because the it is in fact nil despite the '!' following the Swift definition. This must be a documentation bug. The correct code is:

let node = SKSpriteNode(imageNamed: name)
node.userData = NSMutableDictionary()
node.userData["action"] = Action() // custom class

Python’s super(): Not as Simple as You Thought

Austin Bingham from Good With Computers

Python's super() is one of those aspects of the language that many developers use without really understanding what it does or how it works. [1] To many people, super() is simply how you access your base-class's implementation of a method. And while this is true, it's far from the full story.

In this series I want to look at the mechanics and some of the theory behind super(). I want to show that, far from just letting you access your base-class, Python's super() is the key to some interesting and elegant design options that promote composability, separation of concerns, and long-term maintainability. In this first article I'll introduce a small set of classes, and in these classes we'll find a bit of a mystery. In subsequent articles we'll investigate this mystery by seeing how Python's super() really works, looking at topics like method resolution order, the C3 algorithm, and proxy objects.

In the end, you'll find that super() is both more complex than you probably expected, yet also surprisingly elegant and easy-to-understand. This improved understanding of super() will help you understand and appreciate Python on at a deeper level, and it will give you new tools for developing your own Python code.

A note on Python versions

This series is written using Python 3, and some of the examples and concepts don't apply completely to Python 2. In particular, this series assumes that classes are "new-style" classes. ((For a discussion of the difference between "old-style" and "new-style" classes, see the Python wiki.)) In Python 3 all classes are new-style, while in Python 2 you have to explicitly inherit from object to be a new-style class.

For example, where we might use the following Python 3 code in this series:

class IntList:
    . . .

the equivalent Python 2 code would be:

class IntList(object):
    . . .

Also, throughout this series we'll call super() with no arguments. This is only supported in Python 3, but it has an equivalent form in Python 2. In general, when you see a method like this:

class IntList:
    def add(self, x):
        super().add(x)

the equivalent Python 2 code has to pass the class name and self to super(), like this:

class IntList:
    def add(self, x):
        super(IntList, self).add(x)

If any other Python2/3 differences occur in the series, I'll be sure to point them out. [2]

The Mystery of the SortedIntList

To begin, we're going to define a small family of classes that implement some constrained list-like functionality. These classes form a diamond inheritance graph like this:

Inheritance graph

At the root of these classes is SimpleList:

class SimpleList:
    def __init__(self, items):
        self._items = list(items)

    def add(self, item):
        self._items.append(item)

    def __getitem__(self, index):
        return self._items[index]

    def sort(self):
        self._items.sort()

    def __len__(self):
        return len(self._items)

    def __repr__(self):
        return "{}({!r})".format(
            self.__class__.__name__,
            self._items)

SimpleList uses a standard list internally, and it provides a smaller, more limited API for interacting with the list data. This may not be a very realistic class from a practical point of view, but, as you'll see, it let's us explore some interesting aspects of inheritance relationships in Python.

Next let's create a subclass of SimpleList which keeps the list contents sorted. We'll call this class SortedList:

class SortedList(SimpleList):
    def __init__(self, items=()):
        super().__init__(items)
        self.sort()

    def add(self, item):
        super().add(item)
        self.sort()

The initializer calls SimpleList's initializer and then immediately uses SimpleList.sort() to sort the contents. SortedList also overrides the add method on SimpleList to ensure that the list always remains sorted.

In SortedList we already see a call to super(), and the intention of this code is pretty clear. In SortedList.add(), for example, super() is used to call SimpleList.add() - that is, deferring to the base-class - before sorting the list contents. There's nothing mysterious going on...yet.

Next let's define IntList, a SimpleList subclass which only allows integer elements. This list subclass prevents the insertion of non-integer elements, and it does so by using the isinstance() function:

class IntList(SimpleList):
    def __init__(self, items=()):
        for item in items: self._validate(item)
        super().__init__(items)

    @classmethod
    def _validate(cls, item):
        if not isinstance(item, int):
            raise TypeError(
                '{} only supports integer values.'.format(
                    cls.__name__))

    def add(self, item):
        self._validate(item)
        super().add(item)

You'll immediately notice that IntList is structurally similar to SortedList. It provides its own initializer and, like SortedList, overrides the add() method to perform extra checks. In this case, IntList calls its _validate() method on every item that goes into the list. _validate() uses isinstance() to check the type of the candidates, and if a candidate is not an instance of int, _validate() raises a TypeError.

Chances are, neither SortedList nor IntList are particularly surprising. They both use super() for the job that most people find most natural: calling base-class implementations. With that in mind, then, let's introduce one more class, SortedIntList, which inherits from both SortedList and IntList, and which enforces both constraints at once:

class SortedIntList(IntList, SortedList):
    pass

It doesn't look like much, does it? We've simply defined a new class and given it two base classes. In fact, we haven't added any new implementation code at all. But if we go to the REPL we can see that it works as we expect. The initializer sorts the input sequence:

>>> sil = SortedIntList([42, 23, 2])
>>> sil
SortedIntList([2, 23, 42])

but rejects non-integer values:

>>> SortedIntList([3, 2, '1'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "sorted_int_list.py", line 43, in __init__
    for x in items: self._validate(x)
  File "sorted_int_list.py", line 49, in _validate
    raise TypeError(
                '{} only supports integer values.'.format(
                    cls.__name__))
TypeError: SortedIntList only supports integer values.

Likewise, add() maintains both the sorting and type constraints defined by the base classes:

>>> sil.add(-1234)
>>> sil
SortedIntList([-1234, 2, 23, 42])
>>> sil.add('the smallest uninteresting number')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "sorted_int_list.py", line 45, in add
    self._validate(item)
  File "sorted_int_list.py", line 42, in _validate
    raise TypeError(
                '{} only supports integer values.'.format(
                    cls.__name__))
TypeError: SortedIntList only supports integer values.

You should spend some time playing with SortedIntList to convince yourself that it works as expected. You can get the code here.

It may not be immediately apparent how all of this works, though. After all, both IntList and SortedList define add(). How does Python know which add() to call? More importantly, since both the sorting and type constraints are being enforced by SortedIntList, how does Python seem to know to call both of them? This is the mystery that this series will unravel, and the answers to these questions have to do with the method resolution order we mentioned earlier, along with the details of how super() really works. So stay tuned!

[1]If you do know how it works, then congratulations! This series probably isn't for you. But believe me, lots of people don't.
[2]For a detailed look at the differences between the language versions, see Guido's list of differences.

Python’s super() explained

Austin Bingham from Good With Computers

You probably already know how to use Python's super() to call base-class implementations of methods. But do you really know what it's doing? The details of super() are elegant, interesting, and powerful, and while super() is probably more complex than you expect, it's also surprisingly easy to understand. In this series we'll explore super() by first uncovering a bit of a mystery. To resolve the mystery, we'll look a bit under Python's hood to see how super() really works.

The Folly of Floating-Point for Robust Geometric Computation

Rob Smallshire from Good With Computers

Computational geometry - a world where lines have zero thickness, circles are perfectly round and points are dimensionless. Creating robust geometric algorithms using finite precision number types such as float is fiendishly difficult because it's not possible to exactly represent numbers such as one-third, which rather gets in the way of performing seemingly simple operations like dividing a line into exactly three equal segments. In this short series of posts, we'll look at some of the pitfalls of geometric computation, with examples in Python, although the key messages are true with finite-precision floating point numbers in any language.

Rational numbers, modelled by Python's Fraction [1] type can be useful for implementing robust geometric algorithms. These algorithms are often deeply elegant and surprising because they must avoid any detour into the realm of irrational numbers which cannot be represented in finite precision, which means that using seemingly innocuous operations like square root, for example to determine the length of a line using Pythagoras, are not permitted.

One algorithm which benefits from rational numbers is a simple collinearity test determining whether three points lie on the same line. This can be further refined to consider whether a query point \(p\) is above, exactly on, or below the line. Now there are many ways to approach writing such a function, and like many questions in computational geometry the naïve approaches are either overly complex, inefficient, or just plain wrong, albeit in subtle ways. I won't cover the story of how to arrive at a robust algorithm, that story is entertaining covered in Writing Programs for "The Book" by Brian Hayes. [2] Rather, we'll start where Brian leaves off by showing how to implement the algorithm in Python using both floating-point and exact arithmetic so we can understand the tradeoffs between performance and correctness inherent in these choices. Along the way, we'll perhaps touch on some aspects of Python which may be new to you.

Collinearity test

Whether p is above, exactly on, or below line p, r can be determined from the orientation of triangle p, q, r.

You don't need to understand the mathematics of the orientation test to appreciate the point of what we're about to demonstrate, suffice to say that the orientation of three two-dimensional points can be concisely found by computing the sign of the determinant of a three by three matrix containing the \(x\) and \(y\) coordinates of the points in question, where the determinant happens to be the signed area of the triangle formed by the three points:

\begin{equation*} \newcommand{\sgn}{\mathop{\rm sgn}\nolimits} o(p, q, r) = \sgn \begin{vmatrix} 1 & p\_x & p\_y\\1 & q\_x & q\_y\\1 & r\_x & r\_y \end{vmatrix} \end{equation*}

The function \(o\) returns \(+1\) if the polyline \(p\), \(q\), \(r\) executes a left turn and the loop is counterclockwise, \(0\) if the polyline is straight, or \(-1\) if the polyline executes a right turn and the loop is clockwise. These values can in turn be interpreted in terms of whether the query point \(p\) is above, on, or below the line through \(q\) and \(r\).

To cast this formula in Python, we need a sign function and a means of computing the determinant. Both of these are straightforward, although perhaps not obvious, and give us the opportunity to explore a little appreciated aspect of Python. First, the sign() function. You may be surprised to learn − and you wouldn't be alone − that there is no built-in or library function in Python which returns the sign of a number as \(-1\), \(0\) or \(+1\), so we need to roll our own. The simplest solution is probably something like this:

>>> def sign(x):
...     if x < 0:
...         return -1
...     elif x > 0:
...         return 1
...     return 0
...
>>> sign(5)
1
>>> sign(-5)
-1
>>> sign(0)
0

This works well enough. A more elegant solution would be to exploit an interesting behaviour of the bool type, specifically how it behaves under subtraction. Let's do a few experiments:

>>> False - False
0
>>> False - True
-1
>>> True - False
1
>>> True - True
0

Intriguingly, subtraction of bool objects has an integer result! In fact, when used in arithmetic operations this way, True is equivalent to positive one and False is equivalent to zero. We can use this behaviour to implement a most elegant sign() function:

>>> def sign(x):
...     return (x > 0) - (x < 0)
...
>>> sign(-5)
-1
>>> sign(5)
1
>>> sign(0)
0

Now we need to compute the determinant. In our case this turns out to reduce down to simply:

\begin{equation*} \det = (q\_x - p\_x)(r\_y - p\_y) - (q\_y - p\_y)(r\_x - p\_x) \end{equation*}

so the definition of our orientation() function using tuple coordinate pairs for each point becomes just:

def orientation(p, q, r):
    d = (q[0] - p[0]) * (r[1] - p[1]) - (q[1] - p[1]) * (r[0] - p[0])
    return sign(d)

Let's test this on on some examples. First we set up three points a, b and c:

>>> a = (0, 0)
>>> b = (4, 0)
>>> c = (4, 3)

Now we test the orientation of a ➔ b ➔ c:

>>> orientation(a, b, c)
1

This represents a left turn, so the function returns positive one. On the other hand the orientation of a ➔ c ➔ b is negative one:

>>> orientation(a, c, b)
-1

Let's introduce a fourth point d which is collinear with a and c. As expected our orientation() function returns zero for the group a ➔ c ➔ d:

>>> d = (8, 6)
>>> orientation(a, c, d)
0

So far so good. Everything we have done so far is using integer numbers which, in Python, have arbitrary precision. Our function only uses multiplication and subtraction, with no division to result in float values, so all of that precision is preserved. But what happens if we use floating point values as our input data? Let's try some different values using floats. Here are three points which lie on a diagonal line:

>>> e = (0.5, 0.5)
>>> f = (12.0, 12.0)
>>> g = (24.0, 24.0)

As we would expect, our orientation test determines that these points are collinear:

>>> orientation(e, f, g)
0

Furthermore, moving the point e up a little, by increasing its \(y\) coordinate by even a tiny amount, gives the answer we would expect:

>>> e = (0.5, 0.5000000000000018)
>>> orientation(e, f, g)
1

Now let's increase the \(y\) coordinate just a little more. In fact, we'll increase it by the smallest possible amount to the next representable [3] floating point number:

>>> e = (0.5, 0.5000000000000019)
>>> orientation(e, f, g)
0

Wow! According to our orientation function the points e, f and g are collinear again. This cannot possibly be! In fact, we can go through the next 23 successive floating point values up to,

>>> e = (0.5, 0.5000000000000044)
>>> orientation(e, f, g)
0

with our function still reporting that the three points are collinear, until we get to this value,

>>> e = (0.5, 0.5000000000000046)

at which point things settle down and become well behaved again:

>>> orientation(e, f, g)
1

What's happening here is that we've run into problems with the finite precision of Python floats at points very close the diagonal line, and the mathematical assumptions we make in our formula about how numbers work break down due to the fact that floating point numbers are a far from a perfect model of real numbers. Next time, we'll investigate more thoroughly, the behaviour of this orientation test at the limits of floating-point precision.

[1]The Fraction type which models rational numbers is defined in the Python Standard Library fractions module.
[2]Hayes, Brian. (2007) Writing Programs for "The Book". In: Oram, A. & Wilson, G., eds. Beautiful Code O'Reilly Media. pp. 539–551.
[3]In C we could use the nextafter() function to generate the next representable floating point number. Unfortunately, nextafter() is not exposed to Python. Various workarounds are available, including a version built into Numpy, directly calling the C version using ctypes and a pure Python implementation.

XCode 5 versus XCode 6 default generated Game (Sprite Kit) project and scene sizes

Pete Barber from C#, C++, Windows &amp; other ramblings

As a way to learn about Swift I've been trying to write a simple game using Sprite Kit. My initial plan was to just allow a ball to be dragged around the screen and ensure it was constrained by the screen edges. This was a little harder than originally envisioned. This was partly because the default Game project generated by Xcode 6 is slightly different to that generated by Xcode 5 and so none of the existing Sprite Kit tutorials referred to this area.

My main issue was that I could move the ball around and when the drag finished the ball was endowed with velocity so it travelled after release and despite writing some simple code to ensure if the additional travel would take it off the screen this would bound it.

func boundPosToScene(newPos : CGPoint) -> CGPoint
{
  var retVal
  let radius = ball.size.width / 2

  if newPos.xradius < 0
  {
    retVal.xradius
  }

  if newPos.xradius > self.size.width
  {
    retVal.x = self.size.widthradius
  }

  if newPos.yradius < 0
  {
    retVal.yradius;
  }

  if newPos.yradius > self.size.height
  {
    retVal.y = self.size.heightradius
  }

  return retVal;

}

Where ball is a member variable of the class containing this method that is an instance of SKSpriteNode.

Despite this the ball kept disappearing. Reading various online articles, tutorials & StackOverflow posts there seemed to be an issue with Sprite Kit projects always starting up in landscape mode. When I added some debug to this statement (& else where), i.e.


println("view.bounds\(view.bounds), self.frame:\(self.frame), self.size:\(self.size)")

I got:

view.bounds(0.0,0.0,320.0,568.0), scene:(0.0,0.0,1024.0,768.0), scene.size:(1024.0,768.0)

OK. The view looks good but the scene is in landscape and even if orientated to portrait it's a lot larger than the actual view. But why? There were lots of posts about the landscape issues but nothing about the non-aligned size with Xcode 5. Well, a quick test by generating projects with 5 & 6 (NOTE: I'm new to Sprite Kit as well as Swift so I hadn't used it with 5) shows that the generated 'Game' Xcode 5 projects programmatically creates a scene that is sized to the view:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Configure the view.
    SKView * skView = (SKView *)self.view;
    skView.showsFPS = YES;
    skView.showsNodeCount = YES;
    
    // Create and configure the scene.
    SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
    scene.scaleMode = SKSceneScaleModeAspectFill;
    
    // Present the scene.
    [skView presentScene:scene];
}

whereas with XCode 6 it uses an SKS file (called GameScene):

override func viewDidLoad() {
  super.viewDidLoad()

  if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
    // Configure the view.
    let skView = self.view as SKView
    skView.showsFPS = true
    skView.showsNodeCount = true
            
    /* Sprite Kit applies additional optimizations to improve rendering performance */
    skView.ignoresSiblingOrder = true
            
    /* Set the scale mode to scale to fit the window */
    scene.scaleMode = .AspectFill

  }
}

Looking at the GameScene.sks:



You can see that the default scene size is 1024x768, i.e. iPad in landscape mode. Changing this to 320x576 (for iPhone 4 inch) fixes the problem.

NOTE: When making this change make sure you explicitly save the changes. Just modifying the values and building/running the project often seems to result in them being reset. I make sure I navigate away from the Size boxes before pressing Cmd-S.

Of course this is inflexible as it doesn't size to device. As I'd like my app to run on multiple device types I'm probably better of following the Xcode 5 generated code or perhaps just adding re-sizing code once the Scene has been loaded from the SKS file; as I'm not sure what else that gives me.

If you do this. In GameViewController.swift you'll also probably want to change

scene.scaleMode = .AspectFill

to

scene.scaleMode = .ResizeFill

Anyway, this difference in the generated starter apps is something to be aware of & the fact that the initial landscape startup issue reported against Xcode 5 seems to be present though possibly in a different guise. Certainty in the generated app from Xcode 5 it all works fine for me. When I added logging code to display the View and Scene size they were both reported as 320x568.

Subclassing Objective-C classes in Swift and the perils of Initializers

Pete Barber from C#, C++, Windows &amp; other ramblings

--- Begin update

1. The post below applies to Xcode 6 Beta 2. With Beta 3 & 4 the relationships between the Swift and Objective-C regarding the calling of super class initializers has been formalized.

1a. A Swift class can have multiple non-convenience initializers but in this case they must all property initialize any properties. Also, a non-convenience initializer cannot invoke another initializer, i.e. it cannot call self.init(...)

1b. When calling an Objective-C any initializer can be called but unlike what happened in Beta 2 if the initializer invoked is not the Objective-C 'designated' initializer and thus calls it this DOES NOT now result in a virtual like call to an initializer with that signature in the subclass, i.e. the main problem that led to the writing of this blog post.

2. If you want to subclass an SKSpriteNote in Beta 4 the following StackOverflow post shows how.

3. It seems that for some OS classes, in my case SpriteKit either Apple directly or some Xcode magic now provides a shim Swift wrapper of the Objective-C interface (the one for SKSpriteNode has a comment with a date of 2011 but when attempting to "show in Finder" nothing happens). As such all the initializers for SKSpriteNode are marked as convenience except for the 'designated' initializer, e.g.

class MySpriteNode : SKSpriteNode {}

3a. This is now essentially a Swift only project with the MySpriteNode now deriving from SKSpriteNode which is a Swift class. As such the Swift rules must be followed. This means that any convenience initializers in MySpriteNode can only call non-convenience initializers for MySpriteNode and these MUST in turn call a non-convenience initializers in the superclass. In the case of SKSpriteNode there is a only a single designated initializer which is:

   /**
     Designated Initializer
     Initialize a sprite with a color and the specified bounds.
     @param texture the texture to use (can be nil for colored sprite)
     @param color the color to use for tinting the sprite.
     @param size the size of the sprite in points
     */

    init(texture: SKTexture!, color: UIColor!, size: CGSize)

Therefore from a derived class it's impossible to use the super class convenience methods which is what Swift demands but is a shame as it often means re-implementing similar code in the derived class, as per the StackOverflow link.

It's not perfect by any means but it's a lot more consistent than Beta 2. I don't (yet) understand where the magic shim comes from and this is update is based on Beta 4 whereas of writing Beta 5 has just been released!

--- End update

As a way to learn Swift I decided to have a play with Sprite Kit. One of the first things I did was to create a subclass of SKSpriteNode. This has a very handy initializer:

init(imageNamed name: string) (in Swift)
-(instanceType)initWithImageNamed:(NString*)name (in Objective-C)

I then derived from this resulting in:

class Ball : SKSpriteNode
{
    init()
    {
        super.init(imageNamed: "Ball")
    }
}

and added it to my scene as follows:

var ball = Ball()
ball.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame))
self.addChild(ball)

Having successfully written similar code using SKSpriteKitNode directly:

var ball = SKSpriteNode(imageNamed: "Ball")
ball.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame))
self.addChild(ball)

I was expecting it to work. However I received the following runtime error:

fatal error: use of unimplemented initializer 'init(texture:)' for class 'Ploing.Ball'

The odd thing was that it was complaining about the lack of initializer in the Ball class. Why would calling a base class initializer result in a call back to the derived class? I wasn't sure but to work around this I decided to add the missing initializer:

init(texture: SKTexture!)
{
    super.init(texture: texture)
}

Having duly done this I then got the next error:

fatal error: use of unimplemented initializer 'init(texture:color:size:)' for class 'Ploing.Ball'

Ok, same process add that one to the Ball class. 

init(texture texture: SKTexture!, color color: UIColor!, size size: CGSize)
{
    super.init(texture: texture, color: color, size: size)
}

That time it worked but I was puzzled as to why. What seems to be happening is that the derived class is calling the non-designated initializer in the super class which is then calling the designated (or another non-designated one in between). However, when this initializer is called rather than calling the super class implementation it calls one in the derived class, whether it exists or not. In the case of Ball they didn't hence the error.

It turns out that in the middle of the the Initialization section of the The Swift Programming Language there is the following:

Initializer Inheritance and Overriding
Unlike subclasses in Objective-C, Swift subclasses do not not inherit their superclass initializers by default. Swift’s approach prevents a situation in which a simple initializer from a superclass is automatically inherited by a more specialized subclass and is used to create a new instance of the subclass that is not fully or correctly initialized.
If you want your custom subclass to present one or more of the same initializers as its superclass—perhaps to perform some customization during initialization—you can provide an overriding implementation of the same initializer within your custom subclass.
This explains it. Basically, in Swift, initialization methods work like virtual functions in fact super virtual functions. If a super class initializer is invoked and that in turns calls another initializer (designated or not) then it forwards the call to the derived class. The upshot of this seems to be that for any derived class in Swift it would need to re-implement all of the super classes initializers or at least any which may be invoked from the the other initializers.

Time for some experiments

I therefore set out to confirm this with a simple Swift example:

class Foo
{
    var one: Int;
    var two: Int;

    init(value value:Int)
    {
        self.init(value: value, AndAnother:7)
    }

    init(value value:Int, AndAnother value1:Int)
    {
        one = value;
        two = value1;
    }

    func print()
    {
        println("One:\(one), Two:\(two)")
    }
}

class Bar : Foo
{
    init()
    {
        super.init(value:1);
    }
}

let bar = Bar()
bar.print()

This wouldn't compile. 

Designated initializer for 'Foo' cannot delegate (with 'self.init'); did you mean this to be a convenience initializer?
Must call a designated initializer of the superclass 'Foo'

Whereas in Objective-C the designated initializer is effectively advisory, in Swift it's enforced. If a initializer isn't marked with the convenience  keyword then it seems (at least during compilation) all initializers are treated as being the designated initializor and not at the same time. In this case the compilation failed as there was no designated initializer for Bar.init to call and as Foo.init(value value:Int) wasn't marked as a connivence initializer it was assumed to the designated one and is thus forbidden from calling another initializer in its own class; somewhat paradoxically.

These two rules prevent issues that occur with Objective-C's advisory initializer. All but the designated initializer must be prefixed with the convenience keyword. Secondly this is the only initializer permitted to call the super class initializer meaning all the the convenience initializers can only (cross) call other convenience or the designated initializer for their class. Following these rules gives a working example:

class Foo
{
    var one: Int;
    var two: Int;

    convenience init(value value:Int)
    {
        self.init(value: value, AndAnother:7)
    }

    init(value value:Int, AndAnother value1:Int)
    {
        one = value;
        two = value1;
    }

    func print()
    {
        println("One:\(one), Two:\(two)")
    }
}

class Bar : Foo
{
    init()
    {
        super.init(value: 7, AndAnother: 8)
    }
}

let bar = Bar()
bar.print()

Which gives the results:

One:7, Two:8

It also completely bypasses the convenience method of the superclass rendering it useless for calling from a derived class.

As for explaining the original problem this doesn't help either as the new rules prevent the problem. Herein lies the clue though. It suggests the problem is not with Swift classes subclassing other Swift classes but when a Swift class subclasses an Objective-C class.

Subclassing Objective-C from Swift

Time for another experiment but this time using a base class written in Objective-C:

Base.h

@interface Base : NSObject

-(id)initWithValue:(NSInteger) value;
-(id)initWithValue:(NSInteger) value AndAnother:(NSInteger) value1;
-(void)print;

@end

Base.m

#import "Base.h"

@interface Base ()
@property NSInteger one;
@property NSInteger two;
@end

@implementation Base

-(id)initWithValue:(NSInteger) value
{
    return [self initWithValue:value AndAnother:2];
}

-(id)initWithValue:(NSInteger) value AndAnother:(NSInteger) value1
{
    if ([super init])
    {
        self.one = value;
        self.two = value1;
    }
    
    return self;
}

-(void)print
{
    NSLog(@"One:%d, Two:%d", (int)_one, (int)_two);
}

@end

main.swift

class Baz : Base
{
    init()
    {
        super.init(value: 7)
    }

    init(value value:Int, AndAnother value1:Int)
    {
        super.init(value: value, andAnother: value1);
    }
}

var baz = Baz()
baz.print()

Looking at Base it's obvious that the desginated initializer is initWithValue:(int)value AndAnother:(int)value1 whereas Baz is calling a 'convenience' initializer. This compiles happily but when run gives the following error:

fatal error: use of unimplemented initializer 'init(value:andAnother:)' for class 'Test.Baz'

This is the same type of error as in the original SKSpriteNote sample. Here, Baz's initializer is successfully invoking the Base.initWihValue:(int) value but when it invokes Base's designated initializer this is when the super virtual functionality of the initializers comes into play and an attempt is made to call this non-existent method on Baz. This is easily fixed by adding that method such as it calls the super class method as in:

class Baz : Base
{
    init()
    {
        super.init(value: 7)
    }

    init(value value:Int, AndAnother value1:Int)
    {
        super.init(value: value, andAnother: value1);
    }
}

Giving the result:

2014-06-07 17:40:18.632 Test[47394:303] One:7, Two:2

Alternatively and staying true to the Swift way the parameterless intializer which is obviously a convenience initializer should be marked as such. This then causes a compilation failure as this is now forbidden from calling the super class initialzer and instead must make a cross call to the designated initializer giving the following code:

class Baz : Base
{
    convenience init()
    {
        self.init(value: 7, AndAnother: 8)
    }

    init(value value:Int, AndAnother value1:Int)
    {
        super.init(value: value, andAnother: value1);
    }
}

Which gives the result:

2014-06-07 17:40:46.345 Test[47407:303] One:7, Two:8

This differs from the previous version as the connivence initializer now calls the designated one within Baz meaning the  -(id)initWithValue:(NSInteger) value is never called which is why the second value is nolonger 2.

Conclusion

Whilst this explains the behaviour I was seeing when subclassing SKSpriteNode and by providing a mirror of its initializers without marking any as convenience it solves the problem of using the convenient init(imageNamed name: string) method it doesn't do so particularly elegantly nor in a fully Swift style; as it leaves the class with a set of initializers none of which are marked convenience.

A designated initializer could be specified by marking all but the init(texture texture: SKTexture!, color color: UIColor!, size size: CGSize) method as convenience and having them cross call this one. However this would prevent the direct calling of init(imageNamed name: string) which is a lot more convenient than the other methods. 

Ironically, whilst Swift formalizes the designated initializer concept and it looks like it will work well for pure Swift code it can be somewhat inconvenient when subclassing Objective-C classes.

P.S. For those of us who have trouble spelling the keyword convenience is far from convenient. A keywoard to mark the designated initializer may well have been more convenient and probably easier to spell! 

Videos from C++ track on NDC 2014

olvemaudal from Geektalk

As the chair for the C++ track on NDC Oslo, I am happy to report that the C++ track was a huge and massive success! The C++ community in Norway is rather small so even if NDC is a big annual conference for programmers (~1600 geeks) and even with names like Nico, Scott and Andrei as headliners for the track, I was not sure how many people would actually turn up for the C++ talks. I was positively surprised. The first three sessions was packed with people (it was of course a cheap trick to make the three first sessions general/introductory on popular topics). All the other talks were also well attended. The NDC organizers have already confirmed that they want to do this next year as well.

NDC Oslo is an annual five day event. First two days of pre-conference workshops (Andrei did 2 days of Scalable design and implementation using C++) and then 9 tracks of talks for three full days. As usual, NDC records all the talks and generously share all the videos with the world (there are 150+ talks, kudos to NDC!).

I have listed the videos from the C++ track this year. I will also put out a link to the slides when I get them. Enjoy!

Day 1, June 4, 2014

  • C++14, Nico Josuttis (video)
  • Effective Modern C++, Scott Meyers (video)
  • Error Handling in C++, Andrei Alexandrescu (video)
  • Move, noexcept, and push_back(), Nico Josuttis (video)
  • C++ Type Deduction and Why You Care, Scott Meyers (video)
  • Generic and Generative Programming in C++, Andrei Alexandrescu (video)

Day 2, June 5, 2014

  • C++ – where are we headed?, Hubert Matthews (video)
  • Three Cool Things about D, Andrei Alexandrescu (video)
  • The C++ memory model, Mike Long (video, slides)
  • C++ for small devices, Isak Styf (video)
  • Brief tour of Clang, Ismail Pazarbasi (video)
  • Insecure coding in C and C++, Olve Maudal (video, slides)
  • So you think you can int? (C++), Anders Knatten (video)

With this great lineup I hope that NDC Oslo in June has established itself as a significant annual C++ event in Europe together with Meeting C++ Berlin in December and ACCU Bristol in April.

Save the date for NDC next year, June 15-19, 2015. I can already promise you a really strong C++ track at NDC Oslo 2015.

A final note: Make sure you stay tuned on isocpp.org for global news about C++.