Toggle Sidebar   Previous Lesson Complete and Continue  

  Lecture 17. Best Coding Practices 1: Create Modular Services for Specific Tasks.

Homework to Make Sense of The Lecture and Dig Deeper

Exercise 1.

Singleton

You have been reading tons of tutorials and blog posts about singleton and all that, but you still feel like you haven’t truly touched grasp the idea. Therefore, you decided to sit down and play around with the concepts.

(a) In the Sign In View Controller, comment out the implementation of the signInButton_TouchUpInside() at the end of Lecture 17. You’ll write your own code.

@IBAction func signInButton_TouchUpInside(_ sender: Any) {
}
	

(b) To understand how the shared instance in the lecture works, you want to contrast it with the way normal instances behave. Thus, in the AuthService class, you implement an initializer of this class to signal when an instance is created, and implement another sign in method named signInTest().

class AuthService {
init() {
  // YOUR CODE HERE
}
func signInTest() {
  print("signInTest called")
}
	

Then in the signInButton_TouchUpInside() method of the Sign In View Controller, you try to call the signInTest() method using normal instances.

@IBAction func signInButton_TouchUpInside(_ sender: Any) {
  let anAuthServiceInstance = AuthService()
  // YOUR CODE HERE
}
	

Run the app, make the sign in button active, then touch it a few times. What do you observe?

(b) You now know how normal instances behave. You then implement a shared instance of this class.

class AuthService {
  static var sharedInstance = AuthService()
  init() {
    print("An AuthService instance initialized.")
  }
  func signInTest() {
    print("signInTest called")
  }
}
	

Then in the signInButton_TouchUpInside() method of the Sign In View Controller, you use this shared instance to call the signInTest() method instead.

@IBAction func signInButton_TouchUpInside(_ sender: Any) {
  AuthService.sharedInstance.signInTest()
}
	

Again, run the app, make the sign in button active, then touch it a few times. What do you observe in this case? Re-run the app then re-test, does this shared instance get initialized again?

(d) Is it a good idea to use the shared instance in this case? Hint: Normal instances got release after the signInButton method executed.

(e) Now you want to see if using shared instances offers any advantage at all. Therefore, you decide to setup an experiment in which the instance methods from the AuthService might be used extensively. In the AuthService class, you implement another instance method which you want to call in another view controller other than the Sign In View Controller.

class AuthService {
  static var sharedInstance = AuthService()
  init() {
    print("An AuthService instance initialized.")
  }
  func signInTest() {
    print("signInTest called")
  }
  func signUpTest() {
    print("signUpTest called")
  }
  ...
}
	

Then in the Sign Up View Controller, you call this signUpTest() method in the signUpBtn_TouchUpInside() method, using the shared instance. Don’t comment out anything here.

@IBAction func signUpBtn_TouchUpInside(_ sender: Any) {
  // YOUR CODE HERE
  ...
}
	

Now run the app, make the sign in button active, then tap it a few times. Then go to the sign up view and do the same thing to the sign up buttons. What do you observe in this case?

(f) Instead of using the shared instance as in Part (e), you now use a normal instance to call this signUpTest() method.

@IBAction func signUpBtn_TouchUpInside(_ sender: Any) {
  let anAuthServiceInstance = AuthService()
  // YOUR CODE HERE
  ...
}
	

Now test the app the same way as in Part (e). What happens in this case?

Exercise 2.

Modify the deinitializer deinit of the AuthService to signal when an AuthService instance is released from the memory, then redo Exercise 1.

Complete and Continue  
Discussion

13 comments