Skip to content

CaptureContext/swift-associated-objects

Repository files navigation

swift-associated-objects

CI

Associated objects utils

Table of contents

Usage

Basic helpers for object association are available in "AssociatedObjects" product

extension UIViewController {
  var someStoredProperty: Int {
    get { getAssociatedObject(forKey: #function).or(0) }
    set { setAssociatedObject(newValue, forKey: #function)  }
  }
}

let value: Bool = getAssociatedObject(forKey: "value", from: object)

But the full power of associated objects is provided by AssociatedObjectsMacros target

By default @AssociatedObject macro uses .retain(.nonatomic) for classes and .copy(.nonatomic) objc_AssociationPolicy for structs.

import AssociatedObjectsMacros

extension SomeClass {
  @AssociatedObject
  var storedVariableInExtension: Int = 0
  
  @AssociatedObject(readonly: true)
  var storedVariableInExtension: SomeObject = .init()
  
  @AssociatedObject
  var optionalValue: Int?
  
  @AssociatedObject
  var object: Int?
    
  @AssociatedObject(threadSafety: .atomic)
  var threadSafeValue: Int?
    
  @AssociatedObject(threadSafety: .atomic)
  var threadSafeObject: Object?
    
  @AssociatedObject(policy: .assign)
  var customPolicyValue: Int?
    
  @AssociatedObject(policy: .retain(.atomic))
  var customPolicyThreadSafeObject: Object?
}

Macros require swift-syntax compilation, so it will affect cold compilation time

Installation

Basic

You can add AssociatedObjects to an Xcode project by adding it as a package dependency.

  1. From the File menu, select Swift Packages › Add Package Dependency…
  2. Enter "https://github.com/capturecontext/swift-associated-objects.git" into the package repository URL text field
  3. Choose products you need to link them to your project.

Recommended

If you use SwiftPM for your project, you can add AssociatedObjects to your package file.

.package(
  url: "https://github.com/capturecontext/swift-associated-objects.git", 
  .upToNextMinor(from: "0.1.4")
)

Do not forget about target dependencies:

.product(
  name: "AssociatedObjects", 
  package: "swift-associated-objects"
)
.product(
  name: "AssociatedObjectsMacros", 
  package: "swift-associated-objects"
)

Note

The package is compatible with non-Apple platforms, but this package uses conditional compilation, so APIs are only available #if canImport(ObjectiveC)

License

This library is released under the MIT license. See LICENSE for details.