Swift nested class properties
Swift's nested classes are not like Java's nested classes. Well, they're like one kind of Java's nested classes, but not the kind you're thinking of.
In Java, an instance of an inner class automatically has a reference to an instance of the outer class (unless the inner class is declared static
). You can only create an instance of the inner class if you have an instance of the outer class. That's why in Java you say something like this.new nested()
.
In Swift, an instance of an inner class is independent of any instance of the outer class. It is as if all inner classes in Swift are declared using Java's static
. If you want the instance of the inner class to have a reference to an instance of the outer class, you must make it explicit:
class Master {
var test = 2;
class Nested{
init(master: Master) {
let example = master.test;
}
}
func f() {
// Nested is in scope in the body of Master, so this works:
let n = Nested(master: self)
}
}
var m = Master()
// Outside Master, you must qualify the name of the inner class:
var n = Master.Nested(master:m)
// This doesn't work because Nested isn't an instance property or function:
var n2 = m.Nested()
// This doesn't work because Nested isn't in scope here:
var n3 = Nested(master: m)
Do Swift inner classes have access to self of outer class?
AFAIK, you can't access the outer class out-of-the-box.
But what you can do is:
class Outer {
let value = ""
var inner = Inner()
class Inner {
weak var parent: Outer! = nil
func foo() {
let bar = parent.value
}
}
init() {
inner.parent = self
}
}
Or:
class Outer {
class Inner {
unowned let parent: Outer
init(parent: Outer) {
self.parent = parent
}
}
let value = ""
var inner: Inner! = nil
init() {
inner = Inner(parent: self)
}
}
How can I directly access inner class in Swift
You can use a typealias
typealias FranchiseLogic = Logic.FranchiseLogic
This will allow you to use it as FranchiseLogic
in the scope where the typealias
is defined.
I have two inner class in class and i can't init class in swift
The compiler is correct, you are attempting to pass self
to the constructor of Customer
before all stored properties are initialised, as SESSION
won't be initialised until after the Session
object is initialised, but that needs self
- your two requirements are mutually exclusive.
You may need to rethink your architecture; If nothing else, the reference from Customer
to Session
combined with the reference from Session
to Customer
will give you a retain cycle and a memory leak.
If you want to use the current architecture, it is probably best to make the Customer
property of Session
a weak optional to avoid both your initialisation problem and the retain cycle;
class Customer {
let session: Session
let auth: Auth
init() {
self.auth = Auth()
self.session = Session()
session.customer = self
}
class Session {
weak var customer: Customer?
}
}
You could make customer
an implicitly unwrapped optional to avoid the need to unwrap it explicitly each time you refer to it, but you risk a crash if customer
is released or not set:
class Session {
weak var customer: Customer!
}
On a point of style, Swift properties and variables should start with a lower case letter and use camel case, so auth
, session
and userID
, not AUTH
, SESSION
and USER_ID
.
It is a good practice to use inner classes in swift for models?
This is a good practice to make your namespace organized and the question is related to the below one:
Swift nested class properties
How to specify nested custom view class?
At this time, I think that Interface Builder only recognizes the names of Objective-C classes. You can still make Interface Builder find a nested class with the @objc keyword:
class SuperView: UIView {
@objc(SVNestedView) class NestedView: UIImageView {
}
}
Then, in Interface Builder, specify that th view is of class SVNestedView. Since Objective-C isn't namespaced, you still need to pick unique names for each nested class, but at least the Swift side is properly namespaced.
Why would one use nested classes?
You would do that for Namespacing. This way you can have the classes with the same name (like DataGenerator
). But for different purposes. This one would be DataImporter.DataGenerator
class, but you could have another OtherClass.DataGenerator
class which would be a totally different one.
Like in Objective-C when you had 2 or 3 letters before the name of the class (ex: UIView
). But when you created your own, it would be like SSView
You can also declare the inner class private and use it just in that file.
KeyPath to Nested Class
A nested class is referred to by name using standard dot notation, so in your case the nested class is Config.Client
.
As you know a key-path is of the form \<type name>.<path>
so the path you are seeking is \Config.Client.name
.
HTH
How to get the string representation of a nested class
String(reflecting: type(of: theValue))
update by Edwin Vermeer:
For the required conversion to the internal string representation i now have the following function (still in draft)
public class func convertToInternalSwiftRepresentation(type: String) -> String {
if type.components(separatedBy: "<").count > 1 {
// Remove the Array or Set prefix
let prefix = type.components(separatedBy: "<") [0] + "<"
var subtype = type.substring(from: prefix.endIndex)
subtype = subtype.substring(to: subtype.characters.index(before: subtype.endIndex))
return prefix + convertToInternalSwiftRepresentation(type: subtype) + ">"
}
if type.contains(".") {
var parts = type.components(separatedBy: ".")
if parts.count == 2 {
return parts[1]
}
let c = String(repeating:"C", count: parts.count - 1)
var rv = "_Tt\(c)\(parts[0].characters.count)\(parts[0])"
parts.remove(at: 0)
for part in parts {
rv = "\(rv)\(part.characters.count)\(part)"
}
return rv
}
return type
}
Related Topics
Optional Binding with Try? and As? Still Produces an Optional Type
How to Stop Multiple Times Method Calling of Didupdatelocations() in iOS
Application Crashed While Importing Songs from Ipod Library in iPhone for iOS 5.0
Swift - Saving Highscore Using Nsuserdefaults
How to Prevent Uinavigationbar from Covering Top of View in iOS 7
Implement Document Picker in Swift (Ios)
Converting Between Nsdata and Base64 Strings
How to Know If Cellular Access for My iOS App Is Disabled
Uiimagejpegrepresentation Returns Nil
Making a Button Persistent Across All View Controllers
-[Uiapplication Delegate] Must Be Called from Main Thread Only
Presentviewcontroller from Custom Tablecell in Xib
How to Differentiate Between Iphone4 and iPhone 3