I just encounter a strange problem:
var a:ClassA = new ClassA;
var b:ClassA = a;
The program keeps running sometime, the a = null, b = null.
The program is a complex one, I am sure that no part will touch a, and b. My question is, will the runtime(garbage collector) to collect the memory of "a" and then assign a and b to null?
I am confused, thanks!
The garbage collector will reclaim the memory that this instance of ClassA occupies, only once there is no longer a reference to it. As long as a OR b references that memory location, the instance will remain. If these are local variables, then the instance will be picked up by the GC at some point after the function/method exits. If those are instance variables then they will remain until after the defining class' instance is collected.
try
var a:ClassA = new ClassA();
var b:ClassA = a;
The () at the end of the class name calls the constructor so that you actually have your ClassA.
Related
The code snippet shows 4 different ways to access a static property of a struct. Interesting enough that only the 4th one gets the error: "Static member 'size' cannot be used on instance of type 'Learn_W'" Could you help explain why the other three can access the static property of the struct without using Self. as prefix, but only the test4 has to add the Self.as prefix to access the static property size ?
struct Learn_W: View {
private static let size: CGFloat = 50
let test1 = size
var test2 = size
struct test3 {
let a = size
var b = size
}
var test4: CGFloat {
get {return size}
} // "Static member 'size' cannot be used on instance of type 'Learn_W'"
My speculation: the difference is whether the static property is accessed in “Computed property” or “Stored property”. I guess that it’s related to the initialization process of a struct. For stored property, it’s always initialized before an instance is available, so the initialization process would automatically refer the internal “self” as the struct type itself. But “computed property” is not initialized when the instance is available, and it’s evaluated only (not 100% sure, it’s just my speculation) when it’s called in the form instance.computed_property, therefore, it’s being accessed directly though an instance, and in that context the “self” automatically refers to the instance but not type
In all 4 cases, you reference to size is shorthand for self.size.
For each call originating from a static context (the first 3), self is referring to the Learn_W type itself, which has a size, so it works.
In the last case, the call is happening from an instanced context, where self refers to an instance of Learn_W (not Learn_W). Since instances of Learn_W don’t have a size, the lookup is invalid.
I would like to pass a variable to my C function with data type char**.
How do I pass such a variable with Kotlin/Native?
In other words, how do I initialize and use a nested CPointers in Kotlin/Native?
According to the documentation, char** should be mapped to CPointer<CPointerVar<ByteVar>>. So, if you want to allocate a pointer like that, something like this should work:
memScoped {
val charTwoStars = allocPointerTo<CPointerVar<ByteVar>>()
}
As I allocated this inside of the memScoped block, this variable will be accessible in the block, deallocated as soon as the block ends.
I found one way that works. However, it seems inelegant.
val tmp = "".cstr.getPointer(MemScope())
val a = listOf(tmp).toCValues().getPointer(MemScope())
Related question: how do implemented protected members when using the closure approach to OOP?. The problem is most likely the same, although the abstraction that I'm trying to implement is different.
I'm currently implementing a tree structure to represent a scene graph in lua. To do so, lua has several ways of abstracting the concept of classes, and I'm using this one:
new_item = function()
local _self = {}
local _parent = nil
local _children = {}
_self.add_child = function(child)
-- add child to _children
table.insert(_children, child) -- no problems here
-- set child's _parent to _self
child._parent = _self -- this doesn't work: "child._parent" doesn't even exist
end
return _self
end
a = new_item()
b = new_item()
a.add_child(b)
The object returned by new_item is a table with a single item called add_child, which is the function I defined. The local variables _self, _parent and _children are local to the scope of new_item, captured from each "method", and are effectively "private members" of the "class".
Now, to keep the tree consistent, I am creating this function add_child, which will add the passed parameter (which is expected to be another object created with new_item) to the list of children of this object, and set the child's parent to this object.
In C++, C# and Java, I have the notion of "private members", and I can access those of a different instance of the same class. In lua though, these local variables are local to the scope of new_item, so they're not part of the exported object, so I can't access them.
I would like to have a way to implement this abstraction of "accessing private members of a separate instance of the same class", or do something else, so the parent and children links are only modifiable with exported "methods" that can be proven correct.
I think that what I want to do is simply not possible in lua, short of putting _parent inside of _self (therefore making it "public"), and asking pretty please for nobody else to touch it, which is, if I'm not mistaken, how Python deals with this.
However, there might be a way of achieving this that I have not thought of, maybe using a different way to abstract the concept of "class". Does anybody know how to go about implementing the abstraction of "accessing private members of a separate instance of the same class" in lua?
function create_class()
local class = {}
-- when object is garbage-collected, its private data will be auto-removed
local private_data_of_all_objects = setmetatable({}, {__mode = "k"})
function class.create_new_object()
local object = {}
local private = {} -- private fields of this object
private.children = {}
private.parent = nil
private_data_of_all_objects[object] = private
function object.add_child(child)
table.insert(private.children, child)
private_data_of_all_objects[child].parent = object
end
return object
end
return class
end
cl = create_class()
a = cl.create_new_object()
b = cl.create_new_object()
a.add_child(b)
While I was learning suddenly I wondered myself:
why do we have to provide initial values for global(even beyond a class scope) variable but we do not have to do same step with local variables like this? Is there any reason?
if importRequired {
let deleteObjectCount: Int
}
It is allowed, because deleteObjectCount is never been used in your code. And - and this is the difference to global variables - this fact can be checked by the compiler.
You could even do something like:
let importRequired = true
if importRequired {
let deleteObjectCount: Int
deleteObjectCount = 5
print (deleteObjectCount)
}
(e.g. kind-of modify a constant let variable) because the compiler checks that the constant is written only once, and this is done before reading it's value.
In contrast, global variables must be initialized directly, because otherwise the compiler cannot guarantee that they have been so before being initialized (because the could be accessed from anywhere in your program).
void main() {
A one = new A(1);
A two = new A(2);
var fnRef = one.getMyId; //A closure created here
var anotherFnRef = two.getMyId; //Another closure created here
}
class A{
int _id;
A(this._id);
int getMyId(){
return _id;
}
}
According to the dart language tour page referencing methods like this creates a new closure each time. Does anyone know why it does this? I can understand creating closures when defining a method body as we can use variables in an outer scope within the method body, but when just referencing a method like above, why create the closure as the method body isn't changing so it can't use any of the variables available in that scope can it? I noticed in a previous question I asked that referencing methods like this effectively binds them to the object they were referenced from. So in the above example if we call fnRef() it will behave like one.getMyId() so is the closure used just for binding the calling context? ... I'm confused :S
UPDATE
In response to Ladicek. So does that mean that:
void main(){
var fnRef = useLotsOfMemory();
//did the closure created in the return statement close on just 'aVeryLargeObj'
//or did it close on all of the 'veryLargeObjects' thus keeping them all in memory
//at this point where they aren't needed
}
useLotsOfMemory(){
//create lots of 'veryLarge' objects
return aVeryLargeObj.doStuff;
}
Ladicek is right: accessing a method as a getter will automatically bind the method.
In response to the updated question:
No. It shouldn't keep the scope alive. Binding closures are normally implemented as if you invoked a getter of the same name:
class A{
int _id;
A(this._id);
int getMyId() => _id;
// The implicit getter for getMyId. This is not valid
// code but explains how dart2js implements it. The VM has
// probably a similar mechanism.
Function get getMyId { return () => this.getMyId(); }
}
When implemented this way you will not capture any variable that is alive in your useLotsOfMemory function.
Even if it really was allocating the closure inside the useLotsOfMemory function, it wouldn't be clear if it kept lots of memory alive.
Dart does not specify how much (or how little) is captured when a closure is created. Clearly it needs to capture at least the free variables of itself. This is the minimum. The question is thus: "how much more does it capture"?
The general consensus seems to be to capture every variable that is free in some closure. All local variables that are captured by some closure are moved into a context object and every closure that is created will just store a link to that object.
Example:
foo() {
var x = new List(1000);
var y = new List(100);
var z = new List(10);
var f = () => y; // y is free here.
// The variables y and z are free in some closure.
// The returned closure will keep both alive.
// The local x will be garbage collected.
return () => z; // z is free here.
}
I have seen Scheme implementations that only captured their own free variables (splitting the context object into independent pieces), so less is possible. However in Dart this is not a requirement and I wouldn't rely on it. For safety I would always assume that all captured variables (independent of who captures them) are kept alive. I would also make the assumption that bound closures are implemented similar to what I showed above and that they keep a strict minimum of memory alive.
That's exactly right -- the closure captures the object on which the method will be invoked.