Is it possible to reuse an NSKeyedUnarchiver? - cocoa-touch

I'm working on an iOS game and I'm using the NSCoding protocol to save my levels in my editor and to load them in game. I was wondering if it was possible to somehow reuse an NSKeyedUnarchiver after it's been used to load the level. For instance when the player wan't to restart the level. I can't simply create and load a new instance of the level, because I want to keep the same objects, just reset their properties.

You can re-use the data, which is passed down to decoder. You cannot "reset" the existing objects to initial state, though.
While you can do this on your own, I'd suggest to just invalidate the whole tree of objects and re-load them from possibly cached data.
That surely depends on the number of objects, but if you have enough of them for the process to be visibly slow, I believe you have lots of other more important optimisations to do.

Related

Get value of control refnum in one step in SubVI

I'm trying to de-spaghetti a big UI by creating SubVIs that handle only the controls that are relevant, via control refnums.
Now, when extracting the code from the main VI and re-wiring into the subVIs, things get clutter-y.
To read/write these refnums, I have to do a two-step process. First add a terminal to get the control refnum value and then another to get the value of the control.
Wiring the refnums everywhere is not really an option as that will create more spaghetti if there are more than two of them. (usually 4-10)
Is there a better way?
UPDATE
Guys, this is a low-level question about the picture above, not really a queston about large scale architecture / design patterns. I'm using QMH, classes, et.al. where appropriate.
I just feel there should be a way to get the typed value from a typed control ref in one step. It feels kind of common.
In the caller VI, where the controls/indicators actually live, create all your references, then bundle them into clusters of relevant pieces. Pass the clusters into your subVIs, giving a given subVI only the cluster it needs. This both keeps your conpane cleaned up and and makes it clear the interface that each subVI is talking to. Instead of a cluster, you may want to create a LV class to further encapsulate and define the sub-UI operations, but that's generally only on larger projects where some components of the UI will be reused in other UIs.
I'm not sure there is a low-touch way to de-spaghetti a UI with lots of controls and indicators.
My suggestion is to rework the top-level VI into a queued message handler, which would allow you to decouple the user interaction from the application's response. In other words, rather than moving both the controls and the code that handles their changes to subVIs (as you're currently doing), this would keep the controls where they are (so you don't need to use ref nums and property nodes) and only move the code to subVIs.
This design pattern is built-in to recent versions of LabVIEW: navigate to File » Create Project to make LabVIEW generate a project you can evaluate. For more information about understanding how to extend and customize it, see this NI slide deck: Decisions Behind the Design of the
Queued Message Handler Template.
In general, it is not the best practice to read/write value using refnum in perspective of performance. It requires a thread swap to the UI thread each time (which is a heavy process), whereas the FP Terminal is privileged to be able to update the panel without switching execution threads and without mutex friction.
Using references to access value
Requires to update the front panel item every single time they are called.
They are a pass by reference function as opposed to a pass by value function. This means they are essentially pointers to specific memory locations. The pointers must be de-referenced, and then the value in memory updated. The process of de-referencing the variables causes them to be slower than Controls/Indicators, or Local Variables.
Property Nodes cause the front panel of a SubVI to remain in memory, which increases memory use. If the front panel of a SubVI is not displayed, remove property nodes to decrease memory use.
If after this you want to use this method you can use VI scripting to speed up the process: http://sine.ni.com/nips/cds/view/p/lang/en/nid/209110

Tracking model object attributes changes (dirty) in Cocoa

I'm trying to gain insight into the least overhead solution to tracking model object changes in Cocoa.
As I see it there are 3 options:
Use Core Data – lot's of functionality exists for monitoring model object changes (Core Data NSManagedObject - tracking if attribute was changed). I don't know what the overhead of Core Data's management infrastructure is compared to other approaches but it's well established architecture for multi-threading support is a plus. For cross-platform devs there is some downside in not having a readily accessible schema but there are ways around that issue.
Write custom accessors that mark the object as dirty when updating a field with a new value. I've been using this technique with mixed success for quite some time. There are some sticky issues to deal with when sharing objects across threads. You also don't get the benefits of enhancements to automatic synthesis of attributes, etc. You do, however, have greater control of your data store than when using Core Data which can be of benefit (eg. certain operations can be done in a SQL store across many objects in a much more efficient way). Note: There could be a lot of variation here depending on how you write the accessors. For the sake of conversation let's assume setters make a check of the new value against the old one, make appropriate calls to KVO (willChange / didChange), and set a boolean flag (all within synchronization of course).
Use KVO to monitor object fields (ala keyPathsForValuesAffectingValueForKey:) and mark the object as dirty in the KVO callout. I have yet to use this method but it seems like a decent approach. The obvious downside would be the callout every time a setter is called.
I am inclined to think that option 2 has the lowest overhead (in terms of raw processing requirements) given that Core Data and KVO both have some additional overhead either in the generated accessors or in the KVO callouts. The question is, how substantial is the overhead?
And lastly, did I miss an option?
Thanks.

"Delegates or NSNotifications" Adjudging performance of code?

In my application, I have to display image files as a list in tableview, present them in full size and as multiple thumbnails. Hence basically I developed three seperate classes to handle these three views. Now to perform any file operations, I can think of two approaches:
Create appdelegate objects for all these classes, handle them accordingly. When one operation on a photo file is performed in one class, all other classes are notified using NSNotification, keeping the obeserver as Appdelegate object.
Create locally objects for these classes as and when required and assign delegates for performing file operations from one class to other by calling relevant methods.
However, I was not able to judge Which approach would be better in terms of memory usage and performance? Thanks in advance.
Using a one-to-one relationship with direct messaging is the simpler relationship and means of communication/messaging. Favor the delegate callback -- Number 2.
It is also easy to make this design bidirectional -- if the view goes offscreen, you could perform a cancellation. If the load fails, it is easier to inform the controller.
NSNotifications are comparably heavyweight. Not necessary.
Storing a bunch of stuff in a singleton (app delegate) can result in several unnecessarily retained objects. If your program is concurrent, then that can add even more complexity. There's no need for any of this complexity or introduction of mutable global state, and there is no reason presented whereby the objects should have a much larger scope of access and lifetime.
You can optimize for specific needs beyond that, but I don't see any at this time.
It depends a lot on the code and how you are structuring your app. I general use delegates in the following situation:
Where the delegate object exists before and after the main object that needs it. In other words the main object does not need to worry about the lifecycle of it's delegate.
Where the relationship between an object and it's delegate object is a strict one to one. In other words only one delegate object needs to interact with the main object. I have seen situations where delegates are swapped in and out and I would not recommend such code.
Where the main object needs information from the delegate.
I would use notifications where:
Multiple objects need to know of about things happening in another class.
Where the main class does not need to interact with the other classes or even know they exist.
Which ever you choose I would not have more than one file management object for each image. The simple reason being that having multiple means you need to ensure that they all have the same state and therefore are communicating with each other. Otherwise bugs will creep in.

iOS synchronization - what is a good way for a Core Data object to know it has to be pushed to server?

I am building sync functionality between an iPad and a web server. I'm using an approach pretty close to the one described here. I only have one type of object, let's called it a Story, that has to be synchronized. It is a Core Data entity (managed object).
The remaining problem I have to solve is knowing "whenever something changes and needs to be synchronized to the server." One approach would be to go find every piece of code that modifies a Story and have it also set some needsSyncing flag. That does not seem elegant and it seems that over time, developers could forget to update the flag for new types of modification.
Do Core Data objects have a way to observe themselves, so any time any change is made, a particular method is executed? That would make this pretty easy.
Another option might be using the isUpdated method right before doing a save operation on the managed object context. You'd either have to have save called in only one place or do this at every place you save (sounds like the first option). I guess I could make a helper method that goes through all Story objects right before saving and see if any of them need their flag to be set. The only drawback to that is that I'd be traversing all Story objects in the system for any save, even for saves that have nothing to do with a Story.
Anyway I'll stop trying to guess the solution out loud - does anyone have experience with a good way to do this?
SDK has you covered. See the NSManagedObjectContext class reference, at the very end of the page, the MOC will post notifications that you can subscribe to, including NSManagedObjectContextObjectsDidChangeNotification. You can listen for these and do the update call pretty much coincident with saving the MOC.

Saving a list each time it changes

I'm writing an application where a user can add and remove objects from several lists. In order to save their lists even when the application crashes, I want to write them to the disk every time they change. My current plan is to create a class that observes the lists and thus is notified each time one changes, in order to archive them (the lists and all objects in them follow the NSCoding protocol).
It should be noted that I know in advance how many lists there will be, and that these lists are not expected to grow to more than 100 items in length (most will be 10-20).
Is this the best way to achieve what I want to achieve? Should this even be a problem I am worried about, or is it acceptable to only create mementos of these lists when the application exits? I was also considering subclassing NSMutableArray to make a class that saves itself whenever it changes, so that no one class must be aware of all lists that should be saved.
First, good instinct here to worry about the user's data. Yes, of course you should fix your crashes. But even so, you should be protective of the user's data first and foremost. Secondly you should be worried about the user's battery life. So you shouldn't hit their flash drive too often.
If the number of changes aren't large, then I'd recommend creating "list" objects that has-a NSMutableArray (rather than is-a NSMutableArray). You can just write yourself to disk anytime someone calls addItem: in order to always be in sync. If changes happen very quickly, it's pretty easy to build trampolines that will save "every second if there has been a change, but no more often than once a second." (If this is any problem, add a comment and I'll post some code or blog it; it's not difficult.)