Simple / Easy Solution
A common entry point to the application is the delegate applicationDidFinishLaunching . We could just add a static function to each class that we want to notify about initialization, and call it from here.
This first solution is simple and easy to understand. In most cases, this is what I would recommend. Although the following solution provides results that look more like the original initialize() function, it also leads to a slightly longer application startup time. I no longer think it is worth the effort, reducing performance or code complexity in most cases. Simple code is good code.
Read on for another option. You may have a reason to need it (or perhaps part of it).
Not a very simple solution
The first solution does not necessarily scale so well. But what if you create a framework in which you would like your code to be executed without having to call it from the application delegate?
First step
Define the following Swift code. The goal is to provide a simple entry point for any class that you would like to populate with behavior similar to initialize() - this can now be done simply by following SelfAware . It also provides one function to trigger this behavior for each corresponding class.
protocol SelfAware: class { static func awake() } class NothingToSeeHere { static func harmlessFunction() { let typeCount = Int(objc_getClassList(nil, 0)) let types = UnsafeMutablePointer<AnyClass?>.allocate(capacity: typeCount) let autoreleasingTypes = AutoreleasingUnsafeMutablePointer<AnyClass?>(types) objc_getClassList(autoreleasingTypes, Int32(typeCount)) for index in 0 ..< typeCount { (types[index] as? SelfAware.Type)?.awake() } types.deallocate(capacity: typeCount) } }
Second step
This is all well and good, but we still need a way to actually run the function that we defined, i.e. NothingToSeeHere.harmlessFunction() , when the application starts. Earlier in this answer, it was suggested to use Objective-C code for this. However, it looks like we can do what we need using only Swift. For macOS or other platforms where UIApplication is not available, you will need the following options.
extension UIApplication { private static let runOnce: Void = { NothingToSeeHere.harmlessFunction() }() override open var next: UIResponder? {
Third step
Now we have an entry point when starting the application and a way to connect to it from the classes of your choice. All that remains to be done: instead of implementing initialize() , conform to SelfAware and implement the specific method, awake() .
Jordan Smith Mar 16 '17 at 3:03 on 2017-03-16 03:03
source share