pointer to string in Array - swift

During my program execution, I have to load a large array of MyStruct
// Struct definition
struct MyStruct
{
var someString: String = ""
}
// Array definition
var ar = Array<MyStruct>()
The issue is, having all these someString take a large amount of memory and could easily be shaved down because they all have common (large) prefixes. These prefix do vary.
So, I would like to have
struct MyStruct
{
var someString: String = ""
var someString: pointer to a shared string prefix
}
My questions are:
How do I tell swift not to assign and copy the string, but rather a pointer to the string.
How do I obtain the pointer to said strings. Currently, I obtain the prefix using stringByReplacingOccurrencesOfString.
Also, For the strings to be retained somewhere, I plan to put all the prefixes in an array.
Thanks for your help

You can use a static variable to achieve that.
struct MyStruct
{
static var prefix: String = "prefix"
var someString: String = ""
}

Related

How do I use an existing property in a property wrapper when self hasn't been initialized? (SwiftUI)

I have a struct with two variables inside property wrappers. One of the variables is supposed to be computed from the other. When I try to do this, I get the following error:
Cannot use instance member 'name' within property initializer; property initializers run before 'self' is available.
I tried assigning a temporary value to these variables, and then re-assigning them within a custom init() function, but that doesn't seem to work ether. I made a simplified version of the code to see if I could isolate the issue.
import SwiftUI
struct Person {
#State var name: String = ""
#State var nameTag: NameTag = NameTag(words: "")
init(name: String) {
// not changing name and nameTag
self.name = name
nameTag = NameTag(words: "Hi, my name is \(name).")
}
}
class NameTag {
var words: String
init(words: String) {
self.words = words
}
}
var me = Person(name: "Myself")
// still set to initial values
me.name
me.nameTag.words
I noticed that when I changed nameTag to an #ObservedObject, rather than #State, it was able to be re-assigned correctly. Although I don't believe I can change name to #ObservedObject. Could anyone tell me what I'm doing wrong?
To use property wrappers in initializers, you use the variable names with preceding underscores.
And with State, you use init(initialValue:).
struct Person {
#State var name: String
#State var nameTag: NameTag
init(name: String) {
_name = .init(initialValue: name)
_nameTag = .init( initialValue: .init(words: name) )
}
}
Here's what a #State property really looks like, as your tear down levels of syntactic sugar:
name
_name.wrappedValue
$name.wrappedValue
_name.projectedValue.wrappedValue
You can't use the underscore-name outside of the initial type definition.

Values of structs changing when appending to array with protocol type

I have a protocol, and some structs that conform to it, basically in the format shown below. I'm facing an issue where if I append different structs to an array of type [Protocol], the values of the structs are changing in a weird way. However, if I change the type of the array to [Struct1] or [Struct2], and only append the appropriate types, there's no problem.
protocol Protocol {
var id: String { get set }
var name: String { get set }
}
struct Struct1: Protocol {
var id: String = "1"
var name: String = "Struct1"
var uniqueProperty1: String = "uniqueProperty1"
}
struct Struct2: Protocol {
var id: String = "2"
var name: String = "Struct2"
var uniqueProperty2: String = "uniqueProperty2"
}
var structs: [Protocol] = []
let struct1 = Struct1()
let struct2 = Struct2()
structs.append(struct1)
structs.append(struct2)
And I should add, the above code works as expected. It's my project that has a protocol and some structs however that are behaving strangely. What could be causing this issue?
I discovered that if you look at the value of an element within an array of type [Protocol] in the Variables View within the Debug Area, it's possible that it won't reflect that element's actual values.
Here's an example:
You can see that itemsList in cards[2] is nil, but when I print out the same value in the Debugger Output of the Console, it's not nil (has a length of 4):
(lldb) po (cards[2] as? RBListCard)?.itemsList?.count
▿ Optional<Int>
- some : 4
I guess the moral of the story is don't trust the values that show up within the Variables View.

Swift structs defined in separate files do they need initialisers?

I have defined a simple struct in a separate swift file as follows:
import AppKit
//Declaring a new struct for Company
public struct CompanyStruct {
var idCompany: Int
var company: String
var compType: String
}
However, when I try to use this struct it finds the struct if do:
var c = CompanyStruct
and I can select it but I get no parameters prompted when I open the bracket. If I initialise the struct as:
import AppKit
//Declaring a new struct for Company
public struct CompanyStruct {
var idCompany: Int
var company: String
var compType: String
init(idCompany: Int, company: String, compType: String) {
self.idCompany = idCompany
self.company = company
self.compType = compType
}
}
Then it works fine if I use the struct in say View Controller
I thought you did not have to initialise structs? Is it because I define the struct in an separate file?
No you don't need to add initialiser for struct. It has member wise initialiser by default. This is an xCode bug. When it happens just use YourStruct.init and it will show autocompletion. After that you can remove init part and it will work for the rest of the structs.
Structs have a default initializer hence you can create an object without passing parameters.
You can create custom initialiers which you have done.
One thing about structs is you can't create a convenience initializer.
When you use ( ) after structure name when define instance for it you are making initialization automatically.
Let companyStruct = CompanyStruct ( )
But you should give some default values in struct like;
struct CompanyStruct {
var idCompany: Int = 1
}

Changing a struct with one type to another type

I have two structs with the same fields. What is the best way to merge them.
struct Type1{
var variable1:String?
var variable2:Double?
var variable3:String?
var notImporant:String?
}
struct Type2{
var variable1A:String?
var variable2A:String?
var variable3A:String!
}
What is the best way to convert type2 to type1? I am getting a return from an API and parsing it using codable but there are two different structs and I need to get one struct. The data is the same, it is just mapped differently in terms of types. Some of the structs have more info and others have less.
Just make a copy constructor in both structs like so:
struct Type2 {
var variable1A:String?
var variable2A:String?
var variable3A:String!
init(_ otherType: Type1) {
variable1A = otherType.variable1
variable2A = otherType.variable2
variable3A = otherType.variable3
}
}
You cannot cast two unrelated structs. What you can do is define a common Protocol for the two of them, and use them in places where you don't care which underlying object it is.
protocol CommonProtocol {
var variable1: String? { get }
var variable3: String? { get }
}
struct Type1: CommonProtocol {
var variable1:String?
var variable2:Double?
var variable3:String?
var notImporant:String?
}
struct Type2: CommonProtocol {
var variable1A:String?
var variable2A:String?
var variable3A:String!
}
Then, in whichever place you're currently stuck with a type1 instead of a type2, have that function just accept a CommonProtocol instead, and you can use either.
Note that, while both of your types have a variable2, one of them is a Double? while the other is a String?. There are a few different ways to approach that, which I leave to you. I just left it out of the protocol.
On another note, it's Swift standard to capitalize the names of structs (Type1, Type2). In certain instances, you can run into problems if you don't, so I suggest you do.

Change what print(Object) displays in Swift 2.0

I am trying to make my class Digit display the num variable whenever print is called on that object, in Swift 2.0. I thought this might be done with a description variable, but no luck.
class Digit {
var num: Int
var x: Int
var y: Int
var box: Int
var hintList: [Int] = []
var guess: Bool = false
var description: String {
let string = String(num)
return string
}
}
It isn't enough to just add a description variable. You need to also state that your class conforms to CustomStringConvertible (formerly known as Printable in earlier Swift versions).
If you command click the print function, you find the following description.
Writes the textual representation of value, and an optional newline,
into the standard output.
The textual representation is obtained from the value using its protocol
conformances, in the following order of preference: Streamable,
CustomStringConvertible, CustomDebugStringConvertible. If none of
these conformances are found, a default text representation is constructed
in an implementation-defined way, based on the type kind and structure.
The part of which that matters here being that objects passed to print are not checked for whether or not they have a description method, but instead checked for things like whether or not the conform to protocols like CustomStringConvertible which offer data to be printed.
That being said, all you need to do in this case is specify that your class conforms to CustomStringConvertible since you've already added a description variable. If you hadn't already added this, the compiler would complain because this protocol requires that the description variable be implemented.
class Digit: CustomStringConvertible {
var num: Int
var x: Int
var y: Int
var box: Int
var hintList: [Int] = []
var guess: Bool = false
var description: String {
let string = String(num)
return string
}
}