Type-Safe Associated Objects in Swift

Related tags

Utility swift-tsao
Overview

Type-Safe Associated Objects in Swift

Version Platforms Languages License Carthage compatible CocoaPods

TSAO is an implementation of type-safe associated objects in Swift. Objective-C associated objects are useful, but they are also untyped; every associated object is only known to be id at compile-time and clients must either test the class at runtime or rely on it being the expected type.

Swift allows us to do better. We can associate the value type with the key used to reference the value, and this lets us provide a strongly-typed value at compile-time with no runtime overhead¹. What's more, it allows us to store value types as associated objects, not just object types, by transparently boxing the value (although this involves a heap allocation). We can also invert the normal way associated objects work and present this type-safe adaptor using the semantics of a global map from AnyObject to ValueType.

It's also possible to specify the association policy. For all values, atomic/nonatomic retain is supported. For class values, assign is also supported. And for NSCopying values, atomic/nonatomic copy is supported.

To properly use this library, the AssocMap values you create should be static or global values (they should live for the lifetime of the program). You aren't required to follow this rule, but any AssocMaps you discard will end up leaking an object (this is the only way to ensure safety without a runtime penalty).

¹ It does require a type-check, but the optimizer should in theory be able to remove this check.

Usage example

import TSAO

// create a new map that stores the value type Int
// note how this is a global value, so it lives for the whole program
let intMap = AssocMap<Int>()

// fetch the associated object from `obj` using `intMap`
func lookup_int_object(obj: AnyObject) -> Int? {
    // The subscript getter returns a value of type `Int?` so no casting is necessary
    return intMap[obj]
}

// set the associated object for `intMap` on `obj`
func set_int_object(obj: AnyObject, val: Int?) {
    // The subscript setter takes an `Int?` directly, trying to pass
    // a value of any other type would be a compile-time error
    intMap[obj] = val
}

// This map stores values of type NSString with the nonatomic copy policy
let strMap = AssocMap<NSString>(copyAtomic: false)

// fetch the associated object from `obj` using `strMap`
func lookup_str_object(obj: AnyObject) -> NSString? {
    // The subscrip getter returns a value of type `NSString?`
    return strMap[obj]
}

// set the associated object for `strMap` on `obj`
func set_str_object(obj: AnyObject, val: NSString?) {
    // The subscript setter takes an `NSString?` directly, trying to pass
    // an `Int?` like we did with `intMap` would be a compile-time error
    strMap[obj] = val
}
You might also like...
Extensions giving Swift's Codable API type inference super powers 🦸‍♂️🦹‍♀️
Extensions giving Swift's Codable API type inference super powers 🦸‍♂️🦹‍♀️

Welcome to Codextended — a suite of extensions that aims to make Swift’s Codable API easier to use by giving it type inference-powered capabilities an

Swift type modelling the success/failure of arbitrary operations.

Result This is a Swift µframework providing ResultValue, Error. ResultValue, Error values are either successful (wrapping Value) or failed (wrappi

UTIKit is an UTI (Uniform Type Identifier) wrapper for Swift.

UTIKit UTIKit is an UTI (Uniform Type Identifier) wrapper for Swift. Features UTIKit is a full featured library including entire UTI functions. Conver

DeviceGuru is a simple lib (Swift) to know the exact type of the device

DeviceGuru DeviceGuru is a simple lib (Swift) to know the exact type of the device, e.g. iPhone 6 or iPhone 6s Easy to use Light weight From version 5

Protected is a Swift Package that allows you to specify the read and write rights for any type, depending on context by using Phantom types
Protected is a Swift Package that allows you to specify the read and write rights for any type, depending on context by using Phantom types

Protected is a Swift Package that allows you to specify the read and write rights for any type, depending on context by using Phantom types

A Codable Undefinable type for handling JSON undefined values.

Undefinable Overview The purpose of this type is represent the JSON undefined state in Swift structs and classes. The Undefinable enum is a generic wi

A CMIO Camera Extension of the creative camera type, with configuration app

ArtFilm A CMIO Camera Extension of the creative camera type, with configuration app ArtFilm is the sample code for the blog post Getting To Grips With

BCSwiftTor - Opinionated pure Swift controller for Tor, including full support for Swift 5.5 and Swift Concurrency

BCSwiftTor Opinionated pure Swift controller for Tor, including full support for

Swift Markdown is a Swift package for parsing, building, editing, and analyzing Markdown documents.

Swift Markdown is a Swift package for parsing, building, editing, and analyzing Markdown documents.

Comments
  • Added a safe assign initializer.

    Added a safe assign initializer.

    When using init(assign: ()), if value is deallocated, accessing the subscript results in a BAD_ACCESS. Adding a safe assign initializer, where released value will just return nil instead.

    opened by baldoph 0
Releases(v3.0.2)
Owner
Lily Ballard
🏳️‍⚧️🏳️‍🌈 Rustacean 🦀. Open source contributor. Programming language aficionado. She/her.
Lily Ballard
🚀Comprehensive Redux library for SwiftUI, ensures State consistency across Stores with type-safe pub/sub pattern.

??Comprehensive Redux library for SwiftUI, ensures State consistency across Stores with type-safe pub/sub pattern.

Cheng Zhang 18 Mar 9, 2022
MediaType is a library that can be used to create Media Types in a type-safe manner.

This is a general purpose Swift library for a concept of typed treatment for Media Types. We use this library on clients and servers to speak the same dialect and to enjoy all the comfort strong types provide over raw strings.

21Gram Consulting 79 Jul 19, 2022
A Swift collection of unique, ordered objects

Introduction OrderedSet is essentially the Swift equivalent of Foundation's NSOrderedSet/NSMutableOrderedSet. It was created so Swift would have a uni

Weebly 248 Sep 14, 2022
Differific is a diffing tool that helps you compare Hashable objects using the Paul Heckel's diffing algorithm

Differific is a diffing tool that helps you compare Hashable objects using the Paul Heckel's diffing algorithm. Creating a chan

Christoffer Winterkvist 127 Jun 3, 2022
Highlighter will magically find UI objects such as UILabel, UITextView, UITexTfield, UIButton

Highlighter Updates See CHANGELOG for details Intoduction ?? Highlight whatever you want! Highlighter will magically find UI objects such as UILabel,

Kyle Yi 932 Dec 12, 2022
Observe objects in SwiftUI Views which may be nil

ObservedOptionalObject Rationale SwiftUIs @ObservedObject requires that the observed object actually exists. In some cases it's convenient to observe

Matthias Bartelmeß 7 Jul 20, 2022
Getting square objects down round holes

Enough with the bazillion lines of array parsing logic. YOLO. @import YOLOKit; campaigns.reject(^(PPCampaign *campaign){ return campaign.locked;

Max Howell 662 Nov 20, 2022
OTAtomics - Multi-platform Swift thread-safe atomics library

OTAtomics Multi-platform Swift thread-safe atomics library. The library has full

Steffan Andrews 2 Jul 8, 2022
Safe and fast access to SwiftUI PreviewDevice

SafePreviewDevice Motivation At WWDC 2019, Apple announced SwiftUI a new library for building UI in a simple and fast way. Xcode’s SwiftUI preview let

Antonino Francesco Musolino 11 Jun 28, 2022
A declarative, thread safe, and reentrant way to define code that should only execute at most once over the lifetime of an object.

SwiftRunOnce SwiftRunOnce allows a developer to mark a block of logic as "one-time" code – code that will execute at most once over the lifetime of an

Thumbtack 8 Aug 17, 2022