Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Define struct that is treated like a class in Swift

In Swift a String structure is also treated as a class object like when using the NSCoder encodeObject(_:forKey:) method. I do know that String is directly bridged with the objective-c class, NSString, but is there a way to make a custom struct that behaves similarly? Perhaps bridge it to a custom class? I want to be able to do something like this:

struct SortedArray <Value: Comparable> {}

// Would I need to create a bridge between 
// SortedArray and NSSortedArray? Can I even do that?
class NSSortedArray <Value: Comparable> : NSObject, NSCoding {
    required init?(coder aDecoder: NSCoder) {}
    func encodeWithCoder(aCoder: NSCoder) {}
}

class MyClass : NSObject, NSCoding {
    private var objects: SortedArray<String> = SortedArray<String>()
    required init?(coder aDecoder: NSCoder) {
        guard let objects = aDecoder.decodeObjectForKey("objects") as? SortedArray<String> else { return nil }
        self.objects = objects
    }
    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(objects, forKey: "objects")
    }
}
like image 713
NoodleOfDeath Avatar asked Aug 08 '16 19:08

NoodleOfDeath


People also ask

Is struct the same as class Swift?

In Swift, structs are value types whereas classes are reference types. When you copy a struct, you end up with two unique copies of the data. When you copy a class, you end up with two references to one instance of the data. It's a crucial difference, and it affects your choice between classes or structs.

How do you define a struct in Swift?

A struct definition is just a blueprint. To use a struct, we need to create an instance of it. For example, struct Person { var name = " " var age = 0 } // create instance of struct var person1 = Person() Here, we have created an instance by writing the name of the structure Person followed by a default initializer ()

Which is better struct or class in Swift?

When choosing between structs and classes, it's important to remember the key differences: Classes are reference types, and structs are value types. If class inheritance is not needed, structs are faster and more memory efficient. Use structs for unique copies of an object with independent states.

Why use a struct over a class Swift?

It's because classes are reference types, only the memory location is immutable, but the content mutability is independent from it. Hence that makes Struct immutability more guaranteed than Class.


2 Answers

This isn't currently possible. SE-0058 will address it, but is deferred out of Swift 3. A final implementation of SE-0058 would be hoped to handle more than just ObjC bridging; for example allowing C++ or .NET bridging as well in a more generic solution.

like image 72
Rob Napier Avatar answered Sep 30 '22 15:09

Rob Napier


Ultimately, the bridging between String and NSString is quite simple.

NSString only has 2 instance variables (The string pointer nxcsptr, and the length nxcslen). String uses _StringCore, which only has 3 properties (_baseAddress, _countAndFlags, and _owner). The conversion back and forth is hard coded, and called explicitly by the compiler. There's no automatic system implemented for generating classes out of structs, or vice versa.

You'll have to implement a struct/class pair (like with String and NSString), and implement initializers that construct one from the other.

like image 28
Alexander Avatar answered Sep 30 '22 14:09

Alexander