The Process of Designing a Custom Data Structure

var next: WeakRefNode<DataType>?}So far, this is a pretty standard linked list, with the exception that the references are allowed to be deallocated at any time.

The interesting part comes when implementing the .

notify() method.

Since we want this call to disconnect any nodes that contain nil references, we could implement it as a wrapper method for a recursive method that acts a little bit differently depending on whether the current node has a nil reference or not.

The recursive method would be declared like this:func notifyAndClean(node: inout WeakRefNode<DataType>?) -> WeakRefNode<DataType>?What’s going to happen is that .

notify() is going to call this method with the root node as an argument and assign the return value to the root variable.

The notifyAndClean(node:) method then reacts as follows:func notifyAndClean(node: inout WeakRefNode<DataType>?) -> WeakRefNode<DataType>?.{ if let node = node { // The current node exists, // meaning we have not yet // reached the end of the list if let reference = node.

reference { // The current node has a valid reference, // so after notifying, we make a // recursive call and assign the return // value to our next variable, then // return the current node back to our // parent.


performListenerAction() node.

next = notifyAndClean(node.

next) return node } else { // The current node has a nil reference, // and should be bypassed, so we return the // next available node back to our parent.

return notifyAndClean(node.

next) } } else { // Current node is nil, we've // reached the end of our list.

return nil }}This is not a lot of code, but recursive calls are tricky, so make sure you pay attention and read the comments to understand what’s really going on.

Looking at it from a high level perspective, it’s like building a chain of nodes throughout the recursive calls.

When the recursion ends, we collapse the chain, bypassing all nodes that we don’t want to keep.

Note that we are reassigning most (or all) of our .

next pointers as well as the .

root variable every time we call .


This may seem like an unnecessary thing to do, since some (or maybe all) of the pointers won’t change.

However, reassigning a pointer is a small cost and it lets us write a method that is short and easy to read, so we can accept that.

That’s it for this time!.Feel free to comment if you have questions, and follow to get notifications about future articles.

To learn more about iOS Development, check out my previous articles:Using Swift Property Observers To Clean Up ObjectsWhat are Swift Property Observers and how can we use them to clean up our objects for outside developers?medium.

comSeparating Concerns With The Delegate PatternIn this article, we take a look at an example of how the Delegate Pattern can help us write more maintainable code.


comThis story is published in The Startup, Medium’s largest entrepreneurship publication followed by +417,678 people.

Subscribe to receive our top stories here.


. More details

Leave a Reply