destroy displayObject from stage and garbage collector as3? - actionscript

I need help with something very interesting. I try to remove child from parent or fro stage dinamicly but not just removeChild and I want to destroy entire object. Here is very simple example what I want to do.
public function TestProject()
{
holder = new Sprite();
this.addChild(holder);
object1 = new Sprite();
object1.name = "object1";
object1.graphics.beginFill(0x6daeff);
object1.graphics.drawRect(0,0,100,100);
holder.addChild(object1);
stage.addEventListener(MouseEvent.CLICK,onClick);
}
protected function onClick(event:MouseEvent):void
{
var tmp:DisplayObject = holder.removeChild(object1);
tmp = null;
// holder.removeChild(object1) = null; this give me error.
}
//with this code object1 was removed from stage but object1 is not null. When I debug
object1 = flash.display.Sprite ; etc.
I want to remove child and at the same this child to be null.
Any ideas...

To clean up memory you have to destroy all references to your object. In this case:
protected function onClick(event:MouseEvent):void
{
if (holder.contains(object1))
holder.removeChild(object1);
object1 = null;
}
or
protected function onClick(event:MouseEvent):void
{
if (object1.parent)
object1.parent.removeChild(object1);
object1 = null;
}
Note: When you'd applied null to local variable tmp you didn't affect the object1 instance variable.

Thanks for your answer but the point is in this example I write just one object. I Ask when I have 100 object for example. Something like this:
for(var i:int=0;i<holder.numOfChilder;i++)
{
holder.getChildAt(i).addEventListener(Event.MouseEvent,onObjectClick)
}
function onObjectClick():void
{
holder.removeChild(event.currentTarget as DisplayObject) = null;
}
child object are dynamic created and I want dynamic removed

To cleanup object that was created dynamically and to which you have no reference variable, just remove all event listers to it, to make it eligible for GC:
function onObjectClick(event:MouseEvent):void
{
var target:DisplayObject = (event.currentTarget as DisplayObject);
target.removeEventListener(MouseEvent.CLICK, onObjectClick);
holder.removeChild(target);
}
Note: there is no need to set null to you local variable cause it will die automatically since method run will be finished
Note2: u can set useWeakReference=true during adding your listener
to allow your listener being garbage-collected automatically.

Related

How can I use a std::variant with non-trivial user objects (constructed at a later time), and having the visitor use an auto lambda?

I have code that is something like this:
using variant_t = std::variant<MyObj1, MyObj2, MyObj3>;
auto foo(){
variant_t var;
if (condition1){
var = MyObj1{"A String"};
// Other stuff
} else if (condition2) {
var = MyObj2{123, 12345};
// Other stuff
} else if (condition3) {
var = MyObj3{SomeObject};
// Other stuff
} else {
throw std::runtime_error{};
}
return var;
}
int main(){
auto var = foo();
std::visit([&](auto& v){v.call_shared_function_name();}, var);
}
Assuming all of the MyObj's are non-trivial, is there a way to get this to work?
I know std::monostate will allow you to initialize the variant in this way and actually populate it later. But if I do so, I can't have the clean auto& lambda in the visitor and will have to create a visitor/lambda for each type.
I know this might looks silly, or not that clean, but you actually need to initialize with one of those objects:
variant_t var = MyObj1{"A String"};
And it compiles fine, if you can't, please let me know and i'll remove the answer

Dart: List remove not removing Object

The code is on DartPad if you need a complete example (see the while loop towards the end.)
I have a loop,
Place place = places[0];
while (places.isNotEmpty) {
// Get a list of places within distance (we can travel to)
List reachables = place.getReachables();
// Get the closest reachable place
Place closest = place.getClosest(reachables);
// Remove the current place (ultimately should terminate the loop)
places.remove(place);
// Iterate
place = closest;
}
But it's not removing place on the second-to-last line. i.e., the length of the places list remains the same, making it an infinite loop. What's wrong?
This could be because the object in the list has a different hashCode from the object you are trying to remove.
Try using this code instead, to find the correct object by comparing the objects properties, before removing it:
var item = list.firstWhere((x) => x.property1== myObj.property1 && x.property2== myObj.property2, orElse: () => null);
list.remove(item);
Another option is to override the == operator and hashCode in your class.
class Class1 {
#override
bool operator==(other) {
if(other is! Class1) {
return false;
}
return property1 == (other as Class1).property1;
}
int _hashCode;
#override
int get hashCode {
if(_hashCode == null) {
_hashCode = property1.hashCode
}
return _hashCode;
}
}
I have faced the very same issue. Unfortunately I haven't found the root cause, but in the same situation I replaced
places.remove[place]
with
places.removeWhere(p => p.hachCode == place.hashCode)
as a workaround. One more approach was helpful too:
// Get the place from your set:
final place = places.first;
// Replace the place in the set:
places.add(place);
// Remove the place from the set:
places.remove(place);
Most likely place is not in the list for some reason. It's hard to debug without knowing the exact data used, the problem doesn't reproduce with the three-place sample you have in the linked DartPad.
Try figuring out which element is causing the problem. For example you can
try adding an if (!places.contains(place)) print("!!! $place not in $places"); before the remove, or something similar that detects the state when the problem occurs.
This way you can remove object from dynamic list
List data = [
{
"name":"stack"
},
{
"name":"overflow"
}
];
data.removeWhere((item) => item["name"]=="stack");
print(data);
Output
[{name: overflow}]
Use the plugin Equatable
class Place extends Equatable {
...
}
https://pub.dev/packages/equatable
I was having the same issue. I did something like this using removeWhere.
myList.removeWhere((item) => item.id == yourItemId.id)

How can i use user define fucntion to set default value for domain class variable in grails

Here Cycle is a domain class
class Cycle {
int lenght = 42
String[] monitor = new String[length]
static mapping = {
monitor defaultValue:"defaultstrval(length)"
}
def defaultstrval(int length)
{
String[] defaultval =new String[length]
for(int i=0;i<length;i++)
{
defaultval[i]=","
}
return defaultval
}
}
Is Domain class only accept sql function.I really need help with good example.
Rather than using the mapping closure to call your function you can simply call the function from your variable assignment like so
String[] monitor = defaultstravel(length)

how to create a new class instance object dynamically

I have a class
class Account extends Stuff{
String name;
newObject(){
return new Account();
}
}
inside the Stuff class I have a method
//generates list of objects of the same type
//as given object and fills attribute
generateObjectsFromExisting(names)
{
List list = new List();
InstanceMirror instanceMirror = reflect(this);
Symbol formatSymbol = new Symbol("newObject");
for(var name in names){
//calles newObject function from this and returns a new object
var newInstanceObject = instanceMirror.invoke(formatSymbol, []);
Symbol symbol = new Symbol("name");
InstanceMirror field = newInstanceObject.setField(symbol,name);
list.add(newInstanceObject.reflectee)
}
return list;
}
so when writing
main(){
var account = new Account();
List accounts = new List();
accounts = account.generateObjectsFromExisting(['tim','tom']);
print(account.name) // returns null
print(accounts[0].name) // returns tim
print(accounts[1].name) // returns tom
}
the problems with this way are
1 'generateObjectsFromExisting()' is on the 'account' object and not on Account
2 I have to manually add the "newObject" Method to every single class I implement.
I would prefer a static Method like 'Account.generateObjectsFromExisting()'
but how to to access 'this' (since its not available in static)
so I can say "this.new()" or something equivalent to "new Account();" eg "new this();"
and therefor be able to only have one 'newObject' function inside Stuff or maybe wont need it at all.
so now my code would look like this
class Account extends Stuff{
String name;
}
in Stuff
static generateObjectsFromExisting(names)
{
List list = new List();
for(var name in names){
var object = new this();
object.name = name;
list.add(object)
}
return list;
}
in main
main(){
// returns list of Accounts filled with names
accounts = Account.generateObjectsFromExisting(['tim','tom']);
print(accounts[0].name) // returns tim
print(accounts[1].name) // returns tom
}
if you can show me a way to access the Class to do something like this.new(); or new this(); then obviously the class 'Account' needs to be accessed and not the extended 'Stuff'
if the 'this' approach is not possible, then maybe you can show me a way how to access the Class from within an already existing object
like
generateObjectsFromExisting(names)
{
List list = new List();
var class = this.class;
var newObject = class.new():
...
}
or is my current approach the only solution. .. hope not :)
thank you
There are two ways I can think of at the moment. But both of them are pretty close to your initial solution as they both use reflection..
The non-static solution:
class Stuff {
generateObjectsFromExisting(List<String> names) {
var cm = reflectClass(this.runtimeType);
return names.map((name) {
var newInstance = cm.newInstance(const Symbol(''), []).reflectee;
newInstance.name = name;
return newInstance;
}).toList();
}
}
The static solution:
class Stuff {
static generateObjectsFromExisting(type, List<String> names) {
var cm = reflectClass(type);
return names.map((name) {
var newInstance = cm.newInstance(const Symbol(''), []).reflectee;
newInstance.name = name;
return newInstance;
}).toList();
}
}
You would call the static solution like this:
var accounts = Stuff.generateObjectsFromExisting(Account, ['tim', 'tom']);
There might be another solution involving factory constructors but can't think of any right now. Also, this code would easily break when you get another subclass of Stuff that does not have a name attribute. I don't know if you really intended on putting that attribute on Account instead of Stuff.
Also answering you 'Class'-Question. There is no class in Dart, there is only the Type and to get it you can do:
Type type1 = Account;
Type type2 = account.runtimeType;
But the Type doesn't have any methods you could use to create a new instance.

What is the Dart "Expando" feature about, what does it do?

Have been seeing the term "Expando" used recently with Dart. Sounds interesting. The API did not provide much of a clue to me.
An example or two could be most helpful!
(Not sure if this is related, but I am most anxious for a way to add methods (getters) and/or variables to a class. Hoping this might be a key to solving this problem. (hint: I am using the Nosuchmethod method now and want to be able to return the value of the unfound method.))
Thanks in advance,
_swarmii
Just to clarify the difference between expando and maps: as reported in the groups, expando has weak references.
This means that a key can be garbage collected even if it's still present in the expando (as long as there are no other references to it).
For all other intents and purposes it's a map.
Expandos allow you to associate objects to other objects. One very useful example of this is an HTML DOM element, which cannot itself be sub-classed. Let's make a top-level expando to add some functionality to an element - in this case a Function signature given in the typedef statement:
typedef CustomFunction(int foo, String bar);
Expando<CustomFunction> domFunctionExpando = new Expando<CustomFunction>();
Now to use it:
main(){
// Assumes dart:html is imported
final myElement = new DivElement();
// Use the expando on our DOM element.
domFunctionExpando[myElement] = someFunc;
// Now that we've "attached" the function to our object,
// we can call it like so:
domFunctionExpando[myElement](42, 'expandos are cool');
}
void someFunc(int foo, String bar){
print('Hello. $foo $bar');
}
I played with it a little bit. Here's what I've got.
import 'dart:html';
const String cHidden = 'hidden';
class ExpandoElement {
static final Expando<ExpandoElement> expando =
new Expando<ExpandoElement>("ExpandoElement.expando");
final Element element;
const ExpandoElement._expand(this.element);
static Element expand(Element element) {
if (expando[element] == null)
expando[element] = new ExpandoElement._expand(element);
return element;
}
// bool get hidden => element.hidden; // commented out to test noSuchMethod()
void set hidden(bool hidden) {
if (element.hidden = hidden)
element.classes.add(cHidden);
else
element.classes.remove(cHidden);
}
noSuchMethod(InvocationMirror invocation) => invocation.invokeOn(element);
}
final Expando<ExpandoElement> x = ExpandoElement.expando;
Element xquery(String selector) => ExpandoElement.expand(query(selector));
final Element input = xquery('#input');
void main() {
input.classes.remove(cHidden);
assert(!input.classes.contains(cHidden));
input.hidden = true;
assert(x[input].hidden); // Dart Editor warning here, but it's still true
assert(!input.classes.contains(cHidden)); // no effect
input.hidden = false;
assert(!x[input].hidden); // same warning, but we'll get input.hidden via noSuchMethod()
assert(!input.classes.contains(cHidden));
x[input].hidden = true;
assert(input.hidden); // set by the setter of ExpandoElement.hidden
assert(input.classes.contains(cHidden)); // added by the setter
assert(x[input].hidden);
assert(x[input].classes.contains(cHidden)); // this is input.classes
x[input].hidden = false;
assert(!input.hidden); // set by the setter
assert(!input.classes.contains(cHidden)); // removed by the setter
assert(!x[input].hidden);
assert(!x[input].classes.contains(cHidden));
// confused?
assert(input is Element);
assert(x[input] is! Element); // is not
assert(x[input] is ExpandoElement);
assert(x is Expando<ExpandoElement>);
}

Resources