I am new to swift. I want to use none static member of swift class in a static function following is my code. I cannot access none static member of class in static function. Is there a way to access non static member in swift function?
public class Test{
private let testString:String
init(test:String){
testString = test
}
static func Get(url:String){
//Here testString is not accessable..
}
}
No, there isn't a way to access non-static variables in static functions. You can create a static instance of the class (a way a singleton is made) and access its testString variable, though.
There are two ways to achieve such a result. as stated by #Alexander you could create a static instance of the class like a singleton and use that.
Another way you can do is a simple trick like I did recently, you can have a static version of your variable. What I did was listen to the changes that my instance variable would go through using signals. you can do the same with KVO if you haven't overridden the getter for your variable (KVO compatible) or simply set the static variable whenever you change your instance variable although you must do it closure based (Block in OBJC) otherwise it's a whole big circle than never meets.
Whenever your instance variable's value changed you simply apply the same change to your static variable and when needed in static functions, you simply use the static one.
If you're not comfortable with using KVO or react you can also do something else. you can override the getter and setter for your instance variable and set them both to file or UserDefaults and also create a static method and override the getter to read the file with the same key as your instance variable so you don't have to set your static variable every time something changes.
Related
Imagine that we have some singleton object:
class Singleton {
static var shared = Singleton()
private init() { ... }
}
Am I right that if I don't keep the reference in some place, it is initialised again and again due to the ARC every time I access it, like this:
Singleton.shared.doSomething()
var a = Singleton.shared.returnSomething()
If I am, where to keep the reference in the iOS app? In classes that use the singleton?
Or in AppDelegate, to ensure using the same instance without repeated initialisation?
By assigning it to a static value you retain the shared instance and don't need to reinitialise it. Static values exist at class level, not instance level, so are retained, effectively, indefinitely.
What is the difference between global variable and shared instance in Swift? what are their respective field of use? Could anyone clarify their concept based upon Swift.
A global variable is a variable that is declared at the top level in a file. So if we had a class called Bar, you could store a reference to an instance of Bar in a global variable like this:
var bar = Bar()
You would then be able to access the instance from anywhere, like this:
bar
bar.foo()
A shared instance, or singleton, looks like this:
class Bar {
static var shared = Bar()
private init() {}
func foo() {}
}
Then you can access the shared instance, still from anywhere in the module, like this:
Bar.shared
Bar.shared.foo()
However, one of the most important differences between the two (apart from the fact that global variables are just generally discouraged) is that the singleton pattern restricts you from creating other instances of Bar. In the first example, you could just create more global variables:
var bar2 = Bar()
var bar3 = Bar()
However, using a singleton (shared instance), the initialiser is private, so trying to do this...
var baaar = Bar()
...results in this:
'Bar' initializer is inaccessible due to 'private' protection level
That's a good thing, because the point of a singleton is that there is a single shared instance. Now the only way you can access an instance of Bar is through Bar.shared. It's important to remember to add the private init() in the class, and not add any other initialisers, though, or that won't any longer be enforced.
If you want more information about this, there's a great article by KrakenDev here.
Singleton (sharing instance)
Ensure that only one instance of a singleton object is created & It's provide a globally accessible through shared instance of an object that could be shared even across an app.
The dispatch_once function, which executes a block once and only once for the lifetime of an app.
Global variable
Apple documentation says Global variables are variables that are defined outside of any function, method, closure, or type context.
I've made a small class to test when object declaration occurs.
class MyObject
{
static let instance = MyObject();
required init()
{
println("init")
}
}
And when I run this, "init" is only printed when I reference MyObject.instance, meaning that static variables are declared lazily.
The reason I need this to be eager is because
I want to keep a lookup table of object instances for myself (with weak references, don't worry). Instances to be inserted during their init and expose a lookup function, so the functionality is encapsulated.
I'd prefer if I didn't need a separate function at App start to make references to static variables to achieve this.
I am not aware of an eager keyword, but is there an accepted solution to this? Will it be added in Xcode 7?
We used to declare property to pass data between classes as following:
.h file (interface file)
#property (nonatomic) double topSpeed;
.m file (implementation file)
#synthesize topSpeed;
Now there is no interface class, how to pass data between .swift classes ?
Swift provides no differentiation between properties and instance variables (i.e, the underlying store for a property). To define a property, you simply declare a variable in the context of a class.
A swift class is simply a ClassName.swift file.
You declare a class and properties as
class SomeClass {
var topSpeed: Double
var aStrProperty: String
var anIntProperty: Int
//Initializers and other functions
}
You access property values via dot notation. As of Xcode6 beta 4, there also are access modifiers (public, internal and private) in Swift. By default every property is internal. See here for more information.
For more information, refer to the Swift Programming Guide:
Stored Properties and Instance Variables
If you have experience with Objective-C, you may know that it provides
two ways to store values and references as part of a class instance.
In addition to properties, you can use instance variables as a backing
store for the values stored in a property.
Swift unifies these concepts into a single property declaration. A
Swift property does not have a corresponding instance variable, and
the backing store for a property is not accessed directly. This
approach avoids confusion about how the value is accessed in different
contexts and simplifies the property’s declaration into a single,
definitive statement. All information about the property—including its
name, type, and memory management characteristics—is defined in a
single location as part of the type’s definition.
Using Properties.
From the Swift Programming Guide:
Stored Properties and Instance Variables
If you have experience with Objective-C, you may know that it provides
two ways to store values and references as part of a class instance.
In addition to properties, you can use instance variables as a backing
store for the values stored in a property.
Swift unifies these concepts into a single property declaration. A
Swift property does not have a corresponding instance variable, and
the backing store for a property is not accessed directly. This
approach avoids confusion about how the value is accessed in different
contexts and simplifies the property’s declaration into a single,
definitive statement. All information about the property—including its
name, type, and memory management characteristics—is defined in a
single location as part of the type’s definition.
Properties in Objective-C correspond to properties in Swift. There are two ways to implement properties in Objective-C and Swift:
Synthesized/auto-synthesized properties in Objective C -- these are called "stored properties" in Swift. You simply declare it with var topSpeed : Double or let topSpeed : Double = 4.2 in a class declaration, exactly as you would declare a local variable in a function body. You don't get to specify the name of the backing instance variable because, well, there are currently no instance variables in Swift. You must always use the property instead of its backing instance variable.
Manually implemented properties in Objective-C -- these are called "computed properties" in Swift. You declare them in the class declaration like var topSpeed : Double { get { getter code here } set { setter code here } } (for readwrite properties), or var topSpeed : Double { getter code here } (for readonly properties).
It sounds like at least part of your question relates to communicating a given class's interface to other classes. Like Java (and unlike C, C++, and Objective-C), Swift doesn't separate the interface from the implementation. You don't import a header file if you want to use symbols defined somewhere else. Instead, you import a module, like:
import Foundation
import MyClass
To access properties in another class, import that class.
Stored Properties and Instance Variables
If you have experience with Objective-C, you may know that it provides two ways to store values and references as part of a class instance. In addition to properties, you can use instance variables as a backing store for the values stored in a property.
Swift unifies these concepts into a single property declaration. A Swift property does not have a corresponding instance variable, and the backing store for a property is not accessed directly. This approach avoids confusion about how the value is accessed in different contexts and simplifies the property’s declaration into a single, definitive statement. All information about the property—including its name, type, and memory management characteristics—is defined in a single location as part of the type’s definition.
From the Swift Programming Book:
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
I say : typealias is equivalent even more in swift for #synthesize
just look at this link : https://docs.swift.org/swift-book/ReferenceManual/Declarations.html
Is it correct to use objc_setAssociatedObject for class object?
We often simulate class variables using static variables like that:
Objective C Static Class Level variables
but, can we use Associated objects as alternative?
objc_setAssociatedObject([self class], &STRING_KEY, myString, OBJC_ASSOCIATION_RETAIN);
Yes, a class object is a full-fledged object, so you can do anything to it that you can do with a regular object.
However, it is clearer and simpler to use a global variable.
p.s. Associating it with [self class] is not the same as using a global variable, because [self class] gives you the actual class of the current object, which may vary as this method is inherited by subclasses. Whereas with a global variable it would always be the same variable.