I am trying to create a singleton class. For this I have tried to use two different approaches i.e.
1.First approach - Employee class contains two instance properties, a class property that contains the shared instance of the class and a private initializer, i.e.
class Employee
{
var firstName : String
var lastName : String
static let sharedInstance = Employee(firstName: "Payal", lastName: "Gupta")
private init(firstName : String, lastName : String)
{
self.firstName = firstName
self.lastName = lastName
}
}
2.Second approach - Employee2 class contains two class properties, i.e.
class Employee2
{
static var firstName : String = "SomeFirsrName"
static var lastName : String = "SomeLastName"
}
Are these two approaches of making the singleton equivalent? If yes, which one should I use and what are the differences between each of them in respect of singleton?
To make a simple singletone class in Swift you could write:
class SomeManager {
static let sharedInstance = SomeManager()
}
Usage:
SomeManager.sharedInstance
What does it mean?
Since Swift 1.2 it's possible do declare static class properties. So you can implement the singleton like this. There can only be one instance for the lifetime of the application it exists in. Singletons exist to give us singular global state.
The first approach create a singletone having a class with this initialization: Employee(firstName: "Payal", lastName: "Gupta")
The second approach don't create a singletone, is a simple class with two static declared properties.
These two approaches are not equivalent:
The first approach creates an instance of Employee object
The second approach defines two class fields; it does not create any object instances.
In other words, only the first approach creates a singleton. The second approach makes a collection of related fields at the class level.
Try this...
class Employee : NSObject
{
var firstName : String
var lastName : String
class var sharedInstance: Employee {
struct Static {
static let instance: Employee = Employee(firstName: "Payal", lastName: "Gupta")
}
return Static.instance
}
private init(firstName : String, lastName : String)
{
self.firstName = firstName
self.lastName = lastName
}
}
Related
I have a question. I have a DataModel from Class A passing to Class B. I would like Class B to retrieve the changed value from Class A. And They both can edit and share the same data. However, now Class B cannot get any value from Class A. How can i make it
struct DataModel {
var firstName: String = ""
var lastName: String = ""
}
class ClassA {
var dataModel: DataModel
ClassB(dataModel: dataModel)
dataModel.firstName = "ABC"
}
class ClassB {
var dataModel: DataModel
init(dataModel: dataModel) {
self.dataModel = dataModel
dataModel.firstName <--- Print Null
}
}
As struct is a value type when you pass A.dataModel to B, a copy of dataModel is passed to B, not the original instance.
So just use class for your data modal instead of struct if you want to modify A.dataModel in A as well as B
in other words you need to pass reference of A.dataModel to B
class DataModel {
var firstName: String = ""
var lastName: String = ""
}
How to use generics in own created model class?
I have one FeatureListModel class and other have FavoriteModel class. Both store the same properties, the only difference is the different class model name.
I need to display model properties value in ProductDetail controller.
How could I manage this stuff using generics?
Here is my code (Swift 4.2):
1st Model: FavoriteListModel
class FavoriteListModel {
var categoryID: Int?
var item_name: String?
var MRP: String?
}
2nd Model: FeatureListModel
class FeatureListModel {
var categoryID: Int?
var item_name: String?
var MRP: String?
}
I have 8-10 more properties, but this is just some stuff in my code.
Controller - ProductDetailTableViewController
class ProductDetailTableViewController : UITableViewController {
var productDetails: FavoriteListModel!
var productFeatureList: FeatureListModel!
fileprivate func displayProduct() {
if productDetails != nil {
title = productDetails.item_name
categoryID = productDetails.categoryID!
}else if productFeatureList != nil {
categoryID = productFeatureList.categoryID!
title = productFeatureList.item_name
}
}
and in my Product Detail Table Controller, I am accessing model objects and display on the screen.
I don't want if-else check.
You are mixing up generics and protocols. In your case a protocol is preferable.
In ProductDetailTableViewController there is an object which responds to the getter of item_name (by the way please conform to the camelCased naming convention itemName) and categoryID. The type of the object as well as the existence of other properties and functions is not significant.
Create a protocol
protocol Listable {
var itemName : String { get }
var categoryID : Int { get }
}
Then adopt the protocol in your classes (do you really need a class?) and declare at least categoryID as non-optional since you are force unwrapping the value later anyway. Don't use optionals as an alibi not to write an initializer.
class FavoriteListModel : Listable { ...
class FeatureListModel : Listable { ...
In ProductDetailTableViewController rather than two properties declare one property as Listable and instead of objective-c-ish nil checking use optional binding:
var details: Listable!
fileprivate func displayProduct() {
if let productDetails = details {
title = productDetails.itemName
categoryID = productDetails.categoryID
}
}
What you have here is not a use case for the Generics. Generics are used when you have for example a function that does exact same thing but can be used with two different parameter types. That's when you use generics.
Another concept is super class (parent class or base class) which is used when you have a class with common properties and then other classes with those properties and then extra and different unique properties which in this case, each class subclasses the parent class.
What you have here is neither of them. A good architecture for this case is just a single model type (class or struct) and using two different collections (array or set) in your view controller.
You can also create a favorite class or featured class which holds an array with your models.
I have two classes using as singletons.
class Boss {
static let sharedInstance = Boss()
private init() {}
var user_id : String?
var username : String?
}
class Job {
static let sharedInstance = Job()
private init() {}
var job_id : String?
var JobType : String?
}
But after populating the Boss.sharedInstance first, Job.sharedInstance also containing Boss' class variables. But after replacing the sharedInstance with other name (for eg. job_sharedInstance and boss_sharedInstance) respectively, things are working fine. It's quite weird. Can anybody explain me the reason why it would happen like this. Thanks in advance.
Here is the breakpoint. Although Job.sharedInstance does not have user_id, username, etc..., it's showing up.
There is no problem with your code. Both Boss and Job
have a static let sharedInstance property, and these are
completely independent of each other. Different classes
can have static properties with the same name,
and these don't "overlap".
If the debugger shows properties for Job.sharedInstance
which are not even defined in the Job class then this is
a bug in the debugger view.
When in doubt, add print statements to your code.
I was wondering how to accomplish an active record like (not with core data, but with rest, but this part I don't think will be an issue).
The issue its that don't understand well the reflection in swift, and my goal its to have a base class called Collection like (just prototype not really working code here):
public class Collection
{
public var Id: String
public static func Name () -> String
{
// accomplished but not with static method
}
public static func Find () -> [ChildClass] // the child class how can I obtain dynamically?
{
// restful things
return [ChildClass, ChildClass, ...] // rest result maped from json
}
public static func FindById (id : String) {}
// also Save && Delete methods
}
This kind of things I accomplish in c# with WSD-Data exactly in this class
So the usage maybe will:
public class User : Collection
{
public var FirstName: String
public var LastName: String
}
or c# like (dunno if this can be done in swift)
public class User : Collection<User> // we pass user as reference class c# like
{
public var FirstName: String
public var LastName: String
}
I hear also other alternatives to get this done, because don't know so well swift and the way that things are done with it.
Hi I am just trying out grails and trying to learn more on domain class. I have two simple domain classes:
Domain Class 1
package grailtest
class Person {
String firstName
String lastName
int age
String email
static constraints = {
}
}
Domain Class 2
package grailtest
class Customer {
String customerId
Person personInCharge
static constraints = {
}
}
When I do a run-app, I can only see
grailtest.Person : 1
as the Person. How can I default it to a particular value, for instance firstName + lastName, to make the application more user friendly?
in the domain override toString method to what you wanted to be display. restart the app
You can use #ToString in case you want an elaborative way of logging or printing in standard out.
import groovy.transform.ToString
#ToString(includeNames=true, includeFields=true)
class Person {
String firstName
String lastName
int age
String email
}
For example,
def person = new Person(firstName: 'Test', lastName: 'hola',
age: 10, email: 'abc#xyz.com')
would give
Person(firstName:Test, lastName:hola, age:10, email:abc#xyz.com)
Find the view where it displays grailstest.Person: 1 and update it to:
${personInstance.firstName} ${personInstance.lastName}
By default this view should be in "views/person"
You put this code in the view .gsp
${personInstance?.firstname} ${personInstance?.lastname}