Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent object construction in Swift [duplicate]

Tags:

ios

swift

What ways do you know to prevent an object construction using Swift programming language?

In C++ I can simply make the constructor private like this:

struct A {
 private:
  A() {};
};

int main()
{
  // Doesn't compile because the constructor is private.
  A obj;
  return 0;
}

When I do a similar thing in Swift (I tried it in playground) the code compiles just fine:

class A {
  private init() {}
}

let obj = A()

UPDATE:

Ok, this question is marked as a duplicate. But I think this is a misunderstanding. What I'm asking about is what are the best practices you know to prevent object construction in Swift. All I want to achieve is to make it clear to the users of my class that it should not be constructible.

UPDATE 2:

As this question is still here, I think, it needs some more clarifications for those who still can't comprehend what I really want.

Given a class that is used as a wrapper for some useful constants such as the following:

class Constants {
 static let someConstant1 = "CONSTANT_VALUE1"
 static let someConstant2 = "CONSTANT_VALUE2"
 //....etc...
}

what option can be considered as a best practice:

  • Leave it as is and don't worry about the possibility of objects creation outside this class;
  • Add private init() {} to prevent creation of the objects outside the current file;
  • Use init? and return nil to indicate that the objects must not be created as was suggested in the comments.

Hope the question is more clear now.

like image 864
Stan Mots Avatar asked Apr 14 '16 10:04

Stan Mots


1 Answers

From Apple's guide to Swift:

Private access restricts the use of an entity to its own defining source file. Use private access to hide the implementation details of a specific piece of functionality.

Your playground file is all one file, so privacy is not enforced.

For instance, if you create a new project and add a file called Dog.swift to the project that looks like this:

import Foundation

class Dog {
    private init() {
        print("hello")
    }
}

class Cat {
    var d = Dog()
}

in ViewController.swift, you can write:

override func viewDidLoad() {

    let c = Cat()  //=>hello

}

But, if you try:

override func viewDidLoad() {

    let d = Dog() 

}

Xcode will flag that as an error before you even compile the program:

'Dog' cannot be constructed because it has no accessible initializers

Response to comment:

class A {
    init?() {
        return nil
    }

    func greet() {
        print("hello")
    }
}

let x = A()

if let x = x {
    x.greet()
}
else {
    print("nice try")  //=> nice try
}
like image 140
7stud Avatar answered Nov 18 '22 07:11

7stud