class ShareData {
class var sharedInstance: ShareData {
struct Static {
static var instance: ShareData?
static var token: dispatch_once_t = 0
}
dispatch_once(&Static.token) {
Static.instance = ShareData()
}
return Static.instance!
}
var someString : String! //Some String
var selectedTheme : AnyObject! //Some Object
var someBoolValue : Bool!
}
This is my singleton design.However , I want to know how I can clear all its data as and when required?
Also can i have more than one singleton Class??
Since you've only got 3 properties on your singleton it would be far easier just to set up a method that nils each property in turn.
Once you start getting in to how to destroy and recreate your singleton, you get in to the realm of do you actually even want a singleton or should you just be using a regular object.
You are creating a Singleton with the syntax available in... 2014
Today there's a better syntax to define a Singleton class
final class SharedData {
static let sharedInstance = SharedData()
private init() { }
var someString: String?
var selectedTheme: AnyObject?
var someBoolValue: Bool?
func clear() {
someString = nil
selectedTheme = nil
someBoolValue = nil
}
}
As you can see I also added the clearData() method you were looking for.
Related
I am working on project where I have requirements of using singleton.
while using them I stuck on following code
struct User{
var someUserProperty: String?{
willSet{
print(UserManager.shared.sharedUser ?? "")
}
}
}
class UserManager{
static var shared: UserManager = UserManager()
public var sharedUser: User?
/* Private to make this class singleton */
private init() {
self.sharedUser = User(someUserProperty: "someInitialValue")
}
}
class Managers{
static var userManager = UserManager.shared
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
Managers.userManager.sharedUser?.someUserProperty = "someDifferentValue"
}
}
This code throws error in viewDidLoad as it is setting User's property and in that property's observer we are getting same User object.
To solve this, I searched and get solution, which led me to modification in UserManager as follows
class UserManager{
private let concurrentQueue = DispatchQueue(label: "ConcurrentQueue", attributes: .concurrent, target: nil)
static var shared: UserManager = UserManager()
public var sharedUser: User?{
get{
return concurrentQueue.sync {
return self.privateSharedUser
}
}set{
concurrentQueue.async(flags: .barrier){[unowned self] in
self.privateSharedUser = newValue
}
}
}
private var privateSharedUser: User?
/* Private to make this class singleton */
private init() {
self.sharedUser = User(someUserProperty: "someInitialValue")
}
}
I have used dispatch queue to allow read from different places but write in barrier mode so that it will not interrupt read operations. and it worked.
But also following solution works, and that is making me wonder because now I have removed all queuing task and just put get and set.
class UserManager{
private let concurrentQueue = DispatchQueue(label: "ConcurrentQueue", attributes: .concurrent, target: nil)
static var shared: UserManager = UserManager()
public var sharedUser: User?{
get{
return self.privateSharedUser
}set{
self.privateSharedUser = newValue
}
}
private var privateSharedUser: User?
/* Private to make this class singleton */
private init() {
self.sharedUser = User(someUserProperty: "someInitialValue")
}
}
My thinking is that what above code does is that just creating wrapper named sharedUser around actual variable privateUser. So when we set something on sharedUser behind the scenes, it will give you private privateSharedUser whose address is different than sharedUser. Is this the reason ? Or Swift is doing something great behind the scenes ? Please tell me, if any one knows
This question already has answers here:
Using a dispatch_once singleton model in Swift
(30 answers)
Closed 6 years ago.
In a class I would previously create a shared instance like so:
class MenuConfigurator
{
// MARK: Object lifecycle
class var sharedInstance: MenuConfigurator
{
struct Static {
static var instance: MenuConfigurator?
static var token: dispatch_once_t = 0
}
dispatch_once(&Static.token) {
Static.instance = MenuConfigurator()
}
return Static.instance!
}
}
It seems the Swift 3.0 migration tool has changed the block of code to:
class MenuConfigurator
{
private static var __once: () = {
Static.instance = MenuConfigurator()
}()
// MARK: Object lifecycle
class var sharedInstance: MenuConfigurator
{
struct Static {
static var instance: MenuConfigurator?
static var token: Int = 0
}
_ = MenuConfigurator.__once
return Static.instance!
}
}
I am getting the error Use of unresolved identifier Static. What is happening here? Why has the new var private static var __once been created?
dispatch_once_t has been dropped in Swift 3.
The recommended way (at least since Swift 2) to create a singleton is simply
class MenuConfigurator
{
static let sharedInstance = MenuConfigurator()
}
let configurator = MenuConfigurator.sharedInstance
Forget the suggestion of the migrator.
I've been trying to implement Parse in my application and can't seem to get my Subclass to save to the backend. I've been using the guides provided by Parse here and here but still can't get it to work.
My Subclass looks like this:
import Foundation
import Bolts
import Parse
class Fillup : PFObject, PFSubclassing {
#NSManaged var username: String?
#NSManaged var amount: String?
#NSManaged var cost: String?
#NSManaged var date: NSDate?
#NSManaged var location: CLLocation?
override class func initialize() {
var onceToken : dispatch_once_t = 0;
dispatch_once(&onceToken) {
self.registerSubclass()
}
}
static func parseClassName() -> String {
return "Fillup"
}
Accessing the variables works fine using let x = fillup.amount as String!.
However, in my save method the variables always end up being nil.
Here's a small example from my save method:
#IBAction func saveTapped(sender: AnyObject) {
// instantiate new Fillup object
var fillup :Fillup?
//check for nil on variables
if let username = PFUser.currentUser()?.username {
println(username)
fillup?.username = username
}else{
println("Username is nil.")
}
println(fillup?.username)
//save object to backend
fillup?.saveInBackgroundWithBlock({ (success, error) -> Void in
if error != nil {
println("Error: " + error!.localizedDescription)
}else{
println("Fillup saved!")
}
})
}
The output always looks like:
mforrest3
nil
and as the variable is nil it doesn't save successfully to the backend.
I've not included the code for the other variables for simplicity's sake however I think this should still work.
If anyone could point me in the direction of a good guide or help me come up with an answer/reason that would be great.
This line
var fillup :Fillup?
Is not creating a new instance, it's just defining an optional local variable of the appropriate type. You should have
var fillup = Fillup.object()
To actually call the constructor for the class (and allow the compiler to determine the class in this case)
I am using XCode 6.3.1 with Parse 1.7.2.
I defined the following PFObject subclass:
class MyClass: PFObject, PFSubclassing {
#NSManaged var date:NSDate!
#NSManaged var title:String!
#NSManaged var device:String!
#NSManaged var subscribers:NSArray!
#NSManaged var numberOfPictures:NSNumber!
override class func initialize() {
struct Static {
static var onceToken : dispatch_once_t = 0;
}
dispatch_once(&Static.onceToken) {
self.registerSubclass()
}
}
static func parseClassName() -> String {
return "MyClass"
}
}
But when I try to instantiate this class later on in some other code:
var myObject = MyClass()
The compiler gives me an error, saying that I should specify a className parameter to the MyClass constructor.
Did I miss something here?
Parse SDK 1.7.3 seems to solve this bug.
The way you handle did not give it a class name when you initialize, it should be something like this:
var myObject = MyClass("MyClass")
I'm an android app developer and a beginner in swift. I'm trying to implement a singleton class whose data members are shared throughout the app (like Settings).
Getting this done in android is pretty simple but I'm breaking my head to do it in swift.
Below is the code I've tried ..
public class DataSet
{
public var notificationOnOff: Bool!
public var interval: Int!
public var alert: String!
init()
{
self.notificationOnOff = true
self.interval = 1;
self.alert = nil;
}
init (onOff: Bool) {
self.notificationOnOff = onOff
}
init (time: Int) {
self.interval = time
}
init (stop: String) {
self.alert = stop
}
}
This class implementation couldn't persist the data.
Is this the right way of doing it?
EDIT
For example, when I click switch in Settings view controller, I'm setting notificationOnOff like ..
dataset.notificationOnOff = DataSet(onOff: true) // value is set and able to print it
and using this value in another class like...
if dataset.notificationOnOff
{
// do some stuff
}
So basically, the value is persisting only within the Setting class but not when I switch to other class.
Solved!
I have used the below code to successfully implement this..
var instance: DataSet?
class Dataset {
...
class var sharedInstance: DataSet {
struct Static {
static var instance: DataSet?
static var token: dispatch_once_t = 0
}
dispatch_once(&Static.token) {
Static.instance = DataSet()
}
return Static.instance!
}
}
and in the other classes ..
dataset = Dataset.sharedInstance;