Objective-C has a peculiar, but very helpful ability to make an initializer return a different instance than the one the initializer is being called on. You can read about that here.
It's great for things like class clusters, but even for things as simple as ensuring specific instances are returned based on specific conditions (i.e. newing up an Account class with an account number will always return the same instance of the Account class for that number.)
However, in our app, we're using Swift but I don't see any such provisions in this language. Is there such a thing?
Normally we'd simply create a class method to return the instance we're interested in, but while we own the class in question, we do not own the calling code which uses the standard initializer syntax. e.g.
let foo = OurClass()
We want to control which instance is handed back to them based on some external conditions (omitted for clarity here.)
So does Swift have any such mechanisms?
While not as easy or clean as objective-c, hopefully you should be able to achieve your goal using convenience initializers or failable initializers (or both).
A convenience initializer allows you to delegate initialization to another initializer, essentially giving you control of how the object is initialized:
class RecipeIngredient {
var quantity: Int
init(quantity: Int) {
self.quantity = quantity
}
convenience init() {
// You control how the properties are initialized here
if (/* Some external or internal condition */) {
self.init(quantity: 1)
}
else {
self.init(quantity: 2)
}
}
}
// The caller
let mysteryFood = Food()
The failable initializer allows you to return nil in a designated initializer if a condition isn't met or if an error occurs during initialization:
class Account {
var id: Int
// Failable initializers have '?' after init
init?(id: Int) {
// You control if the initialization succeeds or not
if (/* check your db if id is duplicate, for example */) {
return nil
}
// Succeeds
self.quantity = quantity
}
}
// The caller
let account = Account(id: 5)
if (account == nil) {
// It failed
}
else {
// It succeeded
}
In your case, based on your comments, it sounds like you would want to use a failable initializer that returns nil if the caller is attempting to create a duplicate instance.
Hopefully this is along the lines of what you are looking for!