Use PropertyChanged or WeakSubscribe? - xamarin

What is the best way to track a property change?
I have the following concerns why I can't make a decision.
- PropertyChanged can prevent garbage collection from collecting a ViewModel that uses its own PropertyChanged event?
- Could WeakSubscribe be gone at any moment in time when using to track ViewModels own property changes?
Did anyone test this or just know the answer ?

In general, you won't hit problems if you use PropertyChanged strong subscriptions.... However, there are some cases where this can lead to "leaks" - e.g. if you subscribe on a sub-object which has a longer lifetime than a "normal" ViewModel (e.g. a singleton service).
To be safe, though, you can use WeakSubscribe - as long as you store a reference to the returned token from the WeakSubscribe call in a member field in your view, then this will ensure that the subscription remains active for at least as long as your View is in memory.
Regardless of strong or weak, one additional thing to aim for ... is to try to release the event subscription (either strong or weak) as early as you can. This will help prevent event callbacks being fired after the View has disappeared.

Related

Switching to ShouldAlwaysRaiseInpcOnUserInterfaceThread(false) MVVMCross

We are in the process of moving from MVVMCross 4.1 to 4.4. One of the main things for us to consider is the MvxTaskBasedBindingContext that was introduced in 4.2.
In the MVVMCross 4.2 docs it says
To take full advantage of the MvxTaskBasedBindingContext, you should
also call ShouldAlwaysRaiseInpcOnUserInterfaceThread(false); in the
ViewModel constructor.
MvxTaskBasedBindingContext sounds like a good thing and therefore we want to take "full advantage" of it. However unsurprisingly, no longer always raising INotifyPropertyChanged on the UI Thread gives us plenty of Thread Marshalling errors
"Application called an interface that was marshalled for a different thread"
Is there a suggested approach to moving to the ShouldAlwaysRaiseInpcOnUserInterfaceThread(false) model and is only worth it in certain scenarios?
If you take a look at the implementation of MvxNotifyPropertyChanged, you'll see that RaisePropertyChanged by default marshals PropertyChanged events to the UI thread.
So if you are performing Unit Tests on the PropertyChanged event they'll probably break because there is no Dispatcher. Setting ShouldAlwaysRaiseInpcOnUserInterfaceThread(false) will prevent this situation and the raise will be done directly on the thread you are in that moment.
This is also handy when you are subscribed to PropertyChanged in another thread on purpose.
If you want you can set it to false and make a method on your base viewmodel class to do:
this.InvokeOnMainThread(() => this.RaisePropertyChanged(propertyName));
So you always use your RaisePropertyChangedOnMainThread (let's name it like this) and no thread marshalling errors occur.
Source: http://www.damirscorner.com/blog/posts/20140324-HandlingPropertyChangedEventInMvvmCrossViewModelUnitTests.html
HIH

Coordination between classes in Cocoa

I have a program with a lot of controllers which need to co - ordinate with each other . I'm confused about which mechanism to use . What are the pro and con of using :
Delegate
Bindings
Notifications
Key Value observing
Specifically is there any problem with using notifications all over place ? I'm planning to do that as it allows a class to just put out some information and not bother about anything else.
Use delegates if you want your object to have knowledge of specific methods to call when it needs to inform an observer of a state change. Notifications are more appropriate when you have multiple observers. Both of these require manual intervention, i.e. you need to explicitly call the delegate methods or post notifications when state changes.
Bindings and KVO work hand-in-hand, and are automatic ways to update state in one object (e.g. UI) when state in another object changes.

Should I prefer NSNotificactionCenter or .NET events when using Monotouch?

When developing in Monotouch, is it "better" to us real .NET events or NSNotificationCenter?
Simple example: I have a UIViewController. It offers an event "CallbackWhenDisappeared". This event is triggred in ViewDidDisappear. Who ever is interested can register to the event.
I could as well post a "MyFancyControllerHasDisappeared" on the NSNotificationCenter and let interested objects subscribe there.
Which version is to be preferred?
The disadvantage with the .NET events I see: the disappearing controller might hold a reference to the subscribing controller (or the other way round?) and might not be garbage collected.
I also like the loose coupling when using NSNotificationCenter compared to the events where the classes really have to know each other.
Is there a wrong or a right way of doing it?
I actually prefer to use TinyMessenger. Unlike NSNotifications it handles the asynchronicity of the calls for you as part of the framework.
Managed objects also allow for better debuggability especially considering that these are usually cross container calls I find this to be very very useful.
var messageHub = new TinyMessengerHub();
// Publishing a message is as simple as calling the "Publish" method.
messageHub.Publish(new MyMessage());
// We can also publish asyncronously if necessary
messageHub.PublishAsync(new MyMessage());
// And we can get a callback when publishing is completed
messageHub.PublishAsync(new MyMessage(), MyCallback);
// MyCallback is executed on completion
https://github.com/grumpydev/TinyMessenger
There is no really right or wrong, but in my opinion it looks so:
NotificationCenter - You don't know which Objects are interested on the "Events", you send it out and any object can receive it
.Net Events - If there is a direct connection between two objects use this, for example like an UIViewController shows an other UIViewcontroller as Modal. The ModalUIViewcontroller fires an event, if it will hide and the UIViewController is Suscribed to it

NSManagedObject subclass woes

Hey guys, I've got a subclass of an NSManagedObject. In awakeFromInsert and awakeFromFetch I'm calling an initialization method which, among other things, starts an NSTimer.
Now i need a place to invalidate the timer. However, dealloc, finalize, didTurnIntoFault, prepareForDeletion and willTurnIntoFault aren't getting called.
According to the documentation, these methods should all get called when the object is cleared from memory. None of them are, however all the data is saved in the persistent store. I'm puzzled as to why or how.
Is there anything i could be doing that could cause these methods to not get called during the objects life cycle?
Core data controls the lifetime of NSManagedObjects. It's not going to flush an object from memory by itself unless you ask it to. Looking at the documentation, there appear to be two ways:
sending refresh:mergeChanges: to the MOC causes the object to turn into a fault.
sending reset to the MOC causes it to reset itself as if it has just been created.
However, any of the above requires explicit action on your part, so you might as well add a method to the object to invalidate its timer and invoke that.
In fact, your problem probably indicates a design issue. An NSTimer is essentially a user interface event. It should probably be controlled by your MVC controller which sends a message to the model object (the NSManagedObject) to do the action.

Cocoa Controllers - best practice for notifying on completion, for disposal?

I have an ObjC controller object.
After alloc/init of the object, I get it to do a job asynchronously:
[myObject doSomeThingsOverTime];
The method sets things in motion, and then returns immediately.
Question: what is the best way to be notified of the result in the future, so that I can release myObject and react to the work having been completed? Should I observe/post notifications? Or supply the object with a method to callback? Or other?
I'm personally a fan of the notification center route. It allows for more than one observer (may or may not be relevant to you).
The delegate route is also valid, and is used quite frequently in the frameworks.
I think it comes down to personal preference. If it's your own code, you should go for what's most readable and simple for your particular situation. I don't think one is more or less valid than the other.
Have you looked at the NSOperation and NSOperationQueue classes? You can observe the isFinished of an NSOperation object so you will get notified when it is completed.

Resources