I use uxNotification plugin in my application. In the sourcecode I configured it with a property destroyAfterHide set to true and added additional property closeAction set to destroy. However, after I click on the close button and do win.destroy() manually, alert(win) still shows an object, but not undefined or null as expected.
Take a look at what the destroy function actually does. Essentially, it cleans up all of the references to the object that ExtJS created so that it can be garbage collected. If you have any of your own references to the object (the win variable in your case), it can't be garbage collected yet. What you should see, however, is that ExtJS has deemed the object destroyed.
alert(win.destroyed); //should alert 'true'
Then, once your win variable is no longer reachable, it will be picked up by the GC. See this question for an explanation on how GC works in JavaScript. If you don't want to wait for the GC you can reassign the variable:
win = undefined; //or win = null;
Related
When I pass {"silent":true} while setting an attribute in a Backbone model, why doesn't that just suppress the change:attribute event? What is the advantage of firing that event the next time an attribute is changed?
Update
Backbone 0.9.10 changed the behavior of passing { "silent": true }. From the changelog:
Passing {silent:true} on change will no longer delay individual
"change:attr" events, instead they are silenced entirely.
Browse the changelog here
This has confused me for some time as well.
The reason is that {silent:true} does not mean "Do everything as normal, but just don't trigger the event".
From various comments and answers by #jashkenas, what it seems to mean is "simply change the attribute value (and add it to the 'changedAttributes' hash), but defer all other "change-related" activities until later".
'silent' doesn't prevent the change event for that/those properties, it simply queues up the 'announcement' until the next change event is triggered.
So, its probably better named something like defer.
Relevant information:
https://github.com/documentcloud/backbone/pull/850
the point of a "silent" change is that it isn't considered a change from the models point of view. Later, when the change actually occurs, you get the full difference all at once.
https://github.com/documentcloud/backbone/issues/870
Because the point of silent changes is that you're allowed to twiddle with the internal state of your model, temporarily, without actually making a change. Later, when the attribute actually changes, the validation runs and events are emitted. It wouldn't make sense to emit an error event when making a silent change.
Update 4/7/2013
Note: I have not tested this to confirm behavior, this is just based on my reading of the release notes...
As of Backbone 0.9.10, the behavior described above has changed. In that version (and newer), silent:true suppresses the change:attr events entirely - not just delays them.
http://backbonejs.org/#changelog
In backbone 0.9.2 the set function runs validation before any changes are updated.
// Run validation.
if (!this._validate(attrs, options)) return false;
In case of {silent: true} option is passed, the validation code will not be executed.
if (options.silent || !this.validate) return true;
That means, model.set({value: 100}, {silent: true}); is able to set "invalid" value into model, so attributes are updated, but change event's are not firing.
It is useful, then you want to update some field and prevent whole mode validation, so if model is not yet completed, the change still propagated to attributes. But you usually you also want the view to show the change, so you have to manually call model.change() or model.trigger('change:value', model, value).
I have a simple wpf app which has a button that increments a value on clicking. I also have a function that returns the latest value. The default value is 5. I also have a UI test in testcomplete that clicks the button 3 times (so 8). I need to call the .Net function to get this value and assert it. Below is my test code.
After some search I figured out the CLRbridge details and implemented it. However, As you can see below, the UI test instance and the instance on which I am claling the function are different. So, the function returns 5.
My question is, how do I invoke the function from the same instance loaded by testcomplete. Or am I going completely the wrong way for this? I tried both script and UI test with if..then, nothing worked. I have tried both direct instance and calling on the appdomain, both doesnt seem to work.
NOTE: I do understand that I can display the value in a UI control and validate the control. However, i am specifically trying this out for a more complex testing functionality we need in a project.
function Test2()
{
var Increment;
Increment = 0;
//Runs the "TCompTest" tested application.
TestedApps.TCompTest.Run();
//Clicks the 'button1' button.
Aliases.TCompTest.HwndSource_MainWindow.MainWindow.Grid.button1.ClickButton();
//Clicks the 'button1' button.
Aliases.TCompTest.HwndSource_MainWindow.MainWindow.Grid.button1.ClickButton();
//Clicks the 'button1' button.
Aliases.TCompTest.HwndSource_MainWindow.MainWindow.Grid.button1.ClickButton();
//Increment = dotNET.Incrementer.Incr1.zctor().IntValue(true);
Increment = dotNET.Incrementer.Incr1.zctor().IntValue(true);
**OR**
Increment = Sys.Process("TCompTest").AppDomain("TCompTest.exe").dotNET.Incrementer.Incr1.zctor().IntValue(true)
// if(Increment == 8)
// {//Posts an information message to the test log.
Log.Message(Increment);
// }
//Closes the 'HwndSource_MainWindow' window.
Aliases.TCompTest.HwndSource_MainWindow.Close();
}
It should be possible to do what you need from TestComplete. But first of all, to avoid misunderstanding, let me explain the problems with the approaches you tried:
Addressing a class through the "dotNET" object.
When you do this, TestComplete initializes .NET in its service process, loads the specified assembly into it, and works with the classes of this assembly loaded to TestComplete's AppDomain (though living in a separate process). This means that this instance of your assembly has nothing to do with your tested application. So, you can't access your application's data through the dotNET object.
Addressing the Incrementer assembly through the tested application's AppDomain.
OK, in this case you are closer to a solution - you work with the AppDomain of the tested application, so you can access the application's data. However, in your code, you create a new instance of the Incr1 class (via calling zctor). This means that the new class instance will initialize its counter in the constructor, and it will be 5. And this is the value you are getting in your code.
So, the right approach:
Unless the counter field of the Incr1 class containing the current counter value is a static field, you need to address an existing object of the Incr1 class to get the current value of the property, not to create a new class instance. The actual implementation will depend on where you are storing the Incr1 class instance reference in your application. Let's suppose, you store the reference in the Counter property of the MainWindow object:
// Creating an instance of the class somewhere in your code
MainWindow.Counter = new Incr1();
// ...
// And this line of code is in the button click handler
MainWindow.Counter.Increment();
In the described case, you will be able to get the current counter value in your TestComplete script as follows:
var MainWnd = Aliases.TCompTest.HwndSource_MainWindow.MainWindow;
Log.Message(MainWnd.Counter.IntValue(true));
If your setup is different, please describe it - I will try to help accordingly.
I am noticing large amounts of this class being leaked in our automated environment. I tried to search around for this issue but am not finding any available information.
ANTS says that all these instances are GC root objects.
As far as I understand, HwndSubclass is used by the WindowsFormsHost. However, in this particular scenario WindowsFormsHost is not used. This is confirmed by ANTS, which has no knowledge about any instances of WindowsFormsHost.
In what other circumstances is HwndSubclass used and how can I make sure that it gets cleaned out properly?
EDIT:
Just to make sure... the environment is WPF4 (x86) on Win7 (x64).
Looks like it's "by design".
From comments in the HwndSubclass code:
// Allocate a GC handle so that we won't be collected, even if all
// references to us get released. This is because a component outside
// of the managed code (ie. the window we are subclassing) still holds
// a reference to us - just not a reference that the GC recognizes.
and then
// This is LIVE OBJECT because it has a GCHandle. The only time LIVE OBJECTS
// are destroyed is during Shutdown. But Shutdown cleanup is handled through
// the ManagedWndProcTracker and hence no work needs to happen here. PLEASE
// NOTE that reintroducing any cleanup logic in here will conflict with the cleanup
// logic in ManagedWndProcTracker and hence must be avoided. If this instance
// has been disposed its GCHandle is released at the time and hence this object
// is available for GC thereafter. Even in that case since all the cleanup has been
// done during dispose there is no further cleanup required.
As I registered the my object as a property listener. Is it necessary for me to perform any sort of "unlistening" before I release the object.
You should not continue to observe objects you are not retaining (this applies to KVO, delegation, notification, any any other listener pattern). Here is the danger:
You observe an object ("observed") and retain it.
Some other object also retains "observed"
You release "observed"
You deallocate
"observed" changes a property and notifies you
The program crashes
While there are several patterns that you may believe make the above impossible, they are all much more fragile than just unregistering yourself when you release the observed object, particularly in your dealloc.
From what I can find, seems like the IsolatedStorage supposed to be permanent unless the user delete it manually. And the following thread says so too:
Is Silverlight isolated storage treated as permanent, or as a cache?
However seems like if I shut down my application and restart it (as I am debugging on debug mode - not sure if that makes a different), the data I stored earlier is gone.
For example, just as pseudocode:
onClick =
let storage = IsolatedStorageSettings.ApplicationSettings
let x = storage.Item key
storage.Add(key, "Some Value")
on first click event, "x" is null (or empty) as expected. Then on the 2nd time around, x would have "Some Value" - this all works fine as expected. However, when I stop debugging, and restart the application, first time around, "x" goes back to null or empty. Tried the same using SiteSettings.
So seems to me IsolatedStorage is not permanent afterall? Just goes with the lifetime of the application?
1- Use the SiteSettings instead of ApplicationSettings
System.IO.IsolatedStorage.IsolatedStorageSettings.SiteSettings("YourKey")
= yourValue
2- You need to save the data after you change them
System.IO.IsolatedStorage.IsolatedStorageSettings.SiteSettings.Save()