didSet and Getter in Swift array - swift

I want to initialise elements only if an array has been set from outside the current class. Looks like a use for didSet!
// external API
var arr: [Display] = [] {
didSet {
array = arr
initialiseElements(arr: arr)
}
}
// internal
private var array: [Display] = []
but when we return the value from arr it might not be correct - I want to use array as a backing store.
I tried to use a getter on arr but this isn't allowed in Swift. How can I prevent the use of arr within the class, or otherwise ensure we only initiliseElements(:) via calls outside the class?

Why use didSet? why not set?
var arr: [Display] {
set {
array = newValue
initialiseElements(arr: newValue)
}
get {
return self.array
}
}
How can I prevent the use of arr within the class?
You can't, swift doesn't have such access control
otherwise ensure we only initiliseElements(:) via calls outside the class
Again, you can't.
It makes no sense logically as well, think of what you are asking for, you are asking class to declare a variable which itself cant set (read only) but should expose to it outside class to write (read + write) it?
How is that possible? What is the use case you are trying to solve here? If for some reason you ended up with this solution, may be solutioning is wrong! re think of your implementation.
Hope this helps

Related

Can not access to singleton property in swift

I'm trying to create singleton and use it.
But when I try to access to its propery, it shows me error.
How can I fix it?
or
Use
class Test {
let sharedManager: Manager = {
var shared = Manager.shared
shared.str = "update"
return shared
}()
}
You cannot just put statements like print or assignments wherever you want. Generally, they will be inside functions/closures. In my example, I am using a closure to get the Manager and initialize it -- the () at the end of it calls the closure to cause it to run.

Storing a simple array in Realm without creating a managed List in Swift

I have an array of data that doesn't need to be a managed List, meaning I don't need Realm to create a new model for the items with links and the ability to query on the items, etc. I just want a simple array, typically of primitives that don't inherit from Object anyway, that will be persisted with my main object.
The only solution I can think of is to use NSData and NSKeyedArchiver/NSKeyedUnarchiver. Is that the best/only way to do this? Should I just use List even if I don't think I'll need it — what's the best practice for this situation?
Realm doesn't support arrays of primitives (although that functionality is coming soon), so the most straightforward solution is to use a List filled with model objects that just wrap your primitives. There's nothing wrong with archiving to and from NSData and storing the data in your Realm model, though, if you feel that better suits your particular use case.
Here's how I decided to deal with this:
var instructions: [String] {
get {
if _instructions == nil {
_instructions = NSKeyedUnarchiver.unarchiveObject(with: instructionsData) as? [String]
}
return _instructions!
}
set {
instructionsData = NSKeyedArchiver.archivedData(withRootObject: newValue)
_instructions = newValue
}
}
fileprivate var _instructions: [String]? = nil
dynamic var instructionsData = Data()
override static func ignoredProperties() -> [String] {
return ["instructions", "_instructions"]
}
That way I can use the array as I normally would and still have it persisted in a simple way (without having to create an actual List and having to manage a bunch of new models/objects).

Cannot assign to property: function call returns immutable value

Consider the following example.
struct AStruct{
var i = 0
}
class AClass{
var i = 0
var a: A = A(i: 8)
func aStruct() -> AStruct{
return a
}
}
If I try to mutate the the variable of a instance of class AClass it compiles successfully.
var ca = AClass()
ca.a.i = 7
But If I try to mutate the return value of aStruct method, the compile screams
ca.aStruct().i = 8 //Compile error. Cannot assign to property: function call returns immutable value.
Can someone explain this.
This is compiler's way of telling you that the modification of the struct is useless.
Here is what happens: when you call aStruct(), a copy of A is passed back to you. This copy is temporary. You can examine its fields, or assign it to a variable (in which case you would be able to access your modifications back). If the compiler would let you make modifications to this temporary structure, you would have no way of accessing them back. That is why the compiler is certain that this is a programming error.
Try this.
var aValue = ca.aStruct()
aValue.i = 9
Explanation
aStruct() actually returns a copy of the original struct a. it will implicitly be treated as a constant unless you assign it a var.
Try using a class instead of a struct, as it's passed by reference and holds onto the object, while a struct is passed by value (a copy is created).

Lazy load MirrorType

Let's say I have something like this
struct A {
lazy var b: String = { return "Hello" }()
}
If I try to reflect struct A and access the value for b through its MirrorType like so:
var a = A()
var r = reflect(a)
for i in 0..r.count {
let (n, m) = r[i]
println("\(m.value)")
var c = a.b
println("\(m.value)")
}
I get nil in the console both times. Note that the underlying value type is Swift.Optional<Swift.String>, and the variable name is somewhat confusingly b.storage. Is there a way to access the underlying value of a lazy-loaded variable using reflection or initialize it from its MirrorType or am I stuck waiting for someone to write a first-class reflection api for Swift?
The MirorType is very limited in it's functionality. Besides that it's replaced by other functionality in Xcode 7 beta 4.
The point in your case is that the property has not been used yet. So it's actually still nil. The only way to make it not nil is by accessing the property by getting it's value. Unfortunately in Swift you can not do that by executing .valueForKey("propertyName")
If you are looking for a reflection library that is trying to get as much as possible out of Swift, then have a look at EVReflection

Access Class In A Dictionary - Swift

I am now writing a program involves class and dictionaries. I wonder how could I access a class's values inside a dictionary. For the code below how do I access the test1 value using the dictionary. I have tried using dict[1].test1but it doesn't work.
class test {
var tes1 = 1
}
var refer = test()
var dict = [1:refer]
There are a few problems with the line dict[1].test1:
Firstly, the subscript on a dictionary returns an optional type because there may not be a value for the key. Therefore you need to check a value exists for that key.
Secondly, in your class Test you've defined a variable tes1, but you're asking for test1 from your Dictionary. This was possibly just a type-o though.
To solve these problems you're code should look something like this:
if let referFromDictionary = dict[1] {
prinln(referFromDictionary.test1)
}
That's because the subscript returns an optional, so you have to unwrap it - and the most straightforward way is by using optional chaining:
dict[1]?.tes1
but you can also use optional binding:
if let test = dict[1] {
let value = test.tes1
}