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)
}
}
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
.
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)
How to call a function of inner class in outer class?
Your Student_Marks
is just a class definition. Without having an object of the Student_Marks
class in student
, you can not call its member (e.g. cTotal()
).
You can have a look at the sample code below:
class student
{
private:
int admno;
// better std::string here: what would you do if the name exceeds 20 char?
char sname[20];
class Student_Marks {
// ... code
};
Student_Marks student; // create a Student_Marks object in student
public:
// ...other code!
void setStudent()
{
student.sMARKS(); // to set the `Student_Marks`S members!
}
void showData() /* const */
{
// ... code
std::cout << "Total Marks :" << student.cTotal(); // now you can call the cTotal()
}
};
Also have a read: Why is "using namespace std;" considered bad practice?
Accessing view controller methods inside another class [Swift]
I am not sure why getting this error because my DataSource class is inside my ViewController class.
That makes no difference. Declaring one class inside of another merely namespaces the inner class, i.e. it is now called AnimalsVC.DataSource
. It does not cause one instance of the inner class to be able to see magically inside an instance the outer class (and indeed it is completely unclear what instances we would be talking about).
Your nesting of class declarations is useless, so you might as well not do it.
Instead, if DataSource needs to see inside AnimalsVC, do what you would normally do: give your DataSource instance a reference to the AnimalsVC instance:
class AnimalsVC: UIViewController {
var animalsArray = // ...
}
class DataSource: UITableViewDiffableDataSource<Int, Animal> {
weak var vc : AnimalsVC?
// ...
}
When you create your DataSource instance, set its vc
to self
. Now the DataSource can consult the instance properties of the AnimalsVC instance.
(Actually, what I do in my own code is give my UITableViewDiffableDataSource subclass a custom designated initializer. That way, I can create the data source and hand it a reference to the view controller all in one move.)
instance member cannot be used on type error on Swift 4 with nested classes
you could do something like this
class Thing{
var name : String = "hello world"
var t = Thong()
init() {
t.thing = self
t.printMe()
}
class Thong{
weak var thing: Thing!
func printMe(){
print(thing.name)
}
}
}
Why are only final variables accessible in anonymous class?
As noted in comments, some of this becomes irrelevant in Java 8, where final
can be implicit. Only an effectively final variable can be used in an anonymous inner class or lambda expression though.
It's basically due to the way Java manages closures.
When you create an instance of an anonymous inner class, any variables which are used within that class have their values copied in via the autogenerated constructor. This avoids the compiler having to autogenerate various extra types to hold the logical state of the "local variables", as for example the C# compiler does... (When C# captures a variable in an anonymous function, it really captures the variable - the closure can update the variable in a way which is seen by the main body of the method, and vice versa.)
As the value has been copied into the instance of the anonymous inner class, it would look odd if the variable could be modified by the rest of the method - you could have code which appeared to be working with an out-of-date variable (because that's effectively what would be happening... you'd be working with a copy taken at a different time). Likewise if you could make changes within the anonymous inner class, developers might expect those changes to be visible within the body of the enclosing method.
Making the variable final removes all these possibilities - as the value can't be changed at all, you don't need to worry about whether such changes will be visible. The only ways to allow the method and the anonymous inner class see each other's changes is to use a mutable type of some description. This could be the enclosing class itself, an array, a mutable wrapper type... anything like that. Basically it's a bit like communicating between one method and another: changes made to the parameters of one method aren't seen by its caller, but changes made to the objects referred to by the parameters are seen.
If you're interested in a more detailed comparison between Java and C# closures, I have an article which goes into it further. I wanted to focus on the Java side in this answer :)
How to update a variable in a class from a nested class swift
Try this:
override func viewDidLoad() {
var obj = one()
obj.x++;
obj.y++;
obj.z++;
}
Related Topics
Make Code With Firebase Asynchronous
Swift Optional Inout Parameters and Nil
Swiftui Hierarchical Picker With Dynamic Data Crashes
Iboutlet and Ibaction in Swift
How to Init a Uibutton Subclass
Show Am/Pm in Capitals in Swift
How to Convert Timeinterval into Minutes, Seconds and Milliseconds in Swift
Swift & Firebase | Checking If a User Exists with a Username
How to Make an Array of the Current Week Dates Swift
Swift Sphere Combine Star Data
Firebase Snapshot.Key Not Returning Actual Key
How to Use Indices.Contains() in a Collection Extension in Swift 3
Multiple Type Constraints in Swift
How to Check If a Property Value Exists in Array of Objects in Swift
Extension of Dictionary Where <String, Anyobject>
Swift Repl: How to Import, Load, Evaluate, or Require a .Swift File