List all living nodes / actions / animations in a Cocos2D app - ios

Is it possible to list all living nodes (actions and animations are of interest to me too) in a Cocos2D app?
Currently I am fighting memory issues in an app and even though profiler helps with that I would like to try other approaches too.

You can recursively list all child nodes. The start node will be your scene. For actions, I know that you can get number of actions for given node, but i don't know if it is possible to list all actions in some way.
Also, you may use CCTextureCache to check if all of unused textures were already removed from memory. It has no public methods to access this data, but you can see loaded textures names in debugger or add some dumping method.
To prevent memory leak by scheduling some action on node, that you want to remove from parent, send cleanup message to all of nodes before removing from parent. Or if it is instance of your class, make [self cleanup]; in it's onExit() method.
I don't think, that you can receive the list of all created nodes. It sounds like garbage collection in .net =) In objective-C you must watch for leaked objects by yourself.

Related

Should I use a singleton location manager in Swift?

Context:
My app needs the user's current location in several unrelated view controllers and, as of now, I'm creating a CLLocationManager in each of these controllers and requesting the current location over and over.
However, it doesn't look right to me. It's duplicated code and inneficient.
I've seen several references on the internet mentioning a singleton location manager. And I also heard to avoid singletons as much as possible.
Question:
Should I create a singleton class that manages the location? If not, what other solution would you suggest to avoid this duplicated code?
And I also heard to avoid singletons as much as possible
The above statement is correct in case that some dealoocated cycle of the app run needs that data so after it finishes the singleton becomes a problem from memory perspective as it stays alive all the app life cycle , in your case ( all vcs inside the app needs the location ) is the best fit for a singleton to avoid the duplication - less-efficient code and high memory issues
Needless to say 90% of apple classes uses singletons e.x
URLSession.shared
NSNotificationCenter.default
UNUserNotificationCenter.current
UserDefaults.standard
FileManager.default
There is no hard and fast rule. Apple is quite clear that it's fine to instantiate more than one location manager. However, if you do that, you might confuse yourself, because each will need a delegate, each will need its own settings, and so forth. Thus, you are right to be wary of that approach.
It is a standard strategy to pick an instance that persists throughout the life of your app — your app delegate, or your root view controller, for example — and initialize an instance property with a location manager. There is no reason whatever to add the Singleton pattern to the mix; you simply make one once and keep hold of it.
Patterns are not evil. It depends on the user. They are solutions for a specific problems. It depends on how you see your problem and what you want to achieve.
In your case, you need a location manager instance through out your app and you use it in multiple places, so you need a wrapper manager. If you only need one configuration, then it makes sense to use singleton.
Apple is recommending to have a strong reference of the manager as long as you need it. CLLocationManager - Apple Documentation
Create an instance of the CLLocationManager class and store a strong reference to it somewhere in your app.
Keeping a strong reference to the location manager object is required until all tasks involving that object are complete. Because most location manager tasks run asynchronously, storing your location manager in a local variable is insufficient.
If you create a singleton location manager it has to do things differently than other singletons. You can't use the normal delegate pattern for it to inform other objects about the location updates and errors because the normal delegate pattern is a one-to-one relationship. You have to use multiple delegates (the singleton has an array of interested objects and it sends the same message, e.g. location update, to each one). Here's another question about why that's difficult to use:
Multiple Delegates in iOS
You can get around that with notifications but personally I think that's a bad pattern (it decouples things too much and makes it hard to follow paths of responsibility).
The singleton also has to keep track of whether any of its interested objects asked it to stop or start. If they've all asked it to stop then it should power down the updates. If just one wants updates it has to power them back up. Search for all the people building frameworks just to do the same task with the network indicator to see how much trouble this is.
If there's an error with requesting location you have to save that error and when (some later time) an object wants location, you have to retransmit the error. So really you want to have all interested objects connected and listening from the start to avoid that scenario.
I'm sure I could think of more hairy cases that you'd have to deal with.
The in-between option is to create a location manager class with your special setup, error checking and so on, and instantiate one of those whenever you need it. Use the delegate pattern to get messages from it (most will just be passing the messages along directly).

Game network programming synchronizing graphs

I am trying to develop a computer game. I want this game to be multiplayer playable. The game is an arcade space shooter
I plan to run the game at server level and then send updates at the clients. The problem that I am facing is object creation. Let's say if a player shots, the shots themselves are new objects. These will need to be created.
In my game I have a hierarchical structure and the shots themselves will be part of this structure. It will be something like a tree. The problem that I have is identifying objects on the clients and server.
How can I make sure that when the client receives some update then it will update the right objects?
What about new object creation. In my case the scene graph is traversed and each object is updated once it gets updates from the server. But updates which creates new object violates this principle. How should I handle them?
Also, I can't really get updates for the entire scene. I would only need to update specific objects that are visible to the player. What should I do with the rest of the objects that aren't visible? What will happen when they become visible? How can I track when objects become visible to a player?
How can I make sure that when the client receives some update then it
will update the right objects?
You can give an unique id to each object server creates. You might want to create a super Object class containing id and let all other game object classes inherit from it. Or, you can have a map to link between id and object. Or, you can mix them. To get an unique id, server can have a global 'nextID' as int and simply assign to a new object and increase it for next one.
But updates which creates new object violates this principle.
I don't really understand the principle you are talking about but if you are worried about editing your scene graph (or game object list) while traversing it, you can put the newly created objects into another list and just insert the new ones after traversing is done. They will start getting updated from next update. (You should consider how you will remove an object too)
What should I do with the rest of the objects that aren't visible?
What will happen when they become visible?
Well, you are the one who should figure it out because it really depends on your game system. My suggestion is that try to skip their updates and see what problems appear and fix them.
How can I track when objects become visible to a player?
Also, several ways to handle this. Server can detect everything for clients and send only visible object info for each client. Or, each client can detect them and send a request to server for starting to update visible ones. Or, it could be mixed way.
Try server-driven one first and see if server can perform it with maximum number of clients.To use client-driven one, remember each client still needs to update all object location regardless of their visibility but send a request for AI updates for only visible ones.
Again, there are many ways to handle this kind of problems and it really depends on your game system requirements. That's why it's hard to answer your question without knowing your game system well enough. Try to investigate how other similar multiplayer games are designed from some books or google. Good luck!

Check retain count in dealloc method

Recently I was facing an issue where I was navigating from a screen A to screen B. when I was coming back from screen B to screen A, the Live Bytes in the application were not returning to the initial value. After further investigation I found out that I was retaining some global objects in some methods which were called more than once. So I had to fix the calling mechanism of the method.
I fixed the issue, but I was thinking about one alternate solution. What if I simply used a for loop in dealloc which runs depending on the value of retain count. I think it is not advisable to use such approach, but what is the exact problem in this approach if I am sure that the objects are not accessed from anywhere outside the file.
Thanks in advance.
What if I simply used a for loop in dealloc which runs depending on the value of retain count.
I wouldn't be surprised if Xcode detects code like that and energizes the aluminum case of your MacBook Pro with several amps.
I think it is not advisable to use such approach, but what is the
exact problem in this approach if I am sure that the objects are not
accessed from anywhere outside the file.
You're right -- not advisable. There are at least two problems:
It completely breaks the memory management paradigm of Objective-C. You really can't be sure that no other object has retained one of your objects. Just one example: you don't know in your -dealloc method whether any of the objects to which your ivars refer might have been autoreleased.
It's the wrong fix. Doing what you propose doesn't fix bugs in your code, it only covers them up. Your objects should correctly manage the objects that they use, and not worry about what other objects may or may not have retained. If you follow that simple formula, you don't have to worry about whether objects are accessed from "outside the file" or not -- everything just works.
Not only should you not use -retainCount to run the number of retains down to 0, you shouldn't look at -retainCount at all.
Retain count is not for you to count on. There are some internal implementations which increase/decrease the retain count without you know it so using it is not advisable.
You should use the xcode instruments for finding memory leaks which will lead you to places in your code where objects are retained and not released.
or you can just enable ARC and let it manage the memory for you.

MIPS32 - Deallocate memory

Suppose I have a linked list in MIPS32 and at some point I want to remove one of the nodes.
What I do it to make the predecessor node to point to the next node of the node removed.
However the removed node still contains some data. So the question is how do I find out whether that node is usable in future or not?
One suggestion was to create a second linked list containing all the nodes that are usable. However, how would I go to implement such a list? Also, do you think this list should point to all the usable space in memory or just to the one of the removed nodes?
Is there any other better way to accomplish the same result?
Solution:
Whenever we "ask" for new memory we use the sbrk service using syscall. However, if we've removed something from our data structure we may want to use that removed part of memory.
So a solution could be to have a linked list of nodes that could be re-used. Whenever we remove something from our data structure we add the part of memory (i.e. a node) to the linked list that keeps track of re-usable memory.
Therefore, when we've to add something to our data structure we first check whether there is some re-usable node in our "memory linked list". If this is not the case, we can use sbrk as usual.
Whenever we "ask" for new memory we use the sbrk service using syscall. However, if we've removed something from our data structure we may want to use that removed part of memory.
So a solution could be to have a linked list of nodes that could be re-used. Whenever we remove something from our data structure we add the part of memory (i.e. a node) to the linked list that keeps track of re-usable memory.
Therefore, when we've to add something to our data structure we first check whether there is some re-usable node in our "memory linked list". If this is not the case, we can use sbrk as usual.

How to atomatically delete specs of terminated children in a dynamic supervisor

No knowledge of USB needed for this question, just described it as it is to make the example more conrete.
I'm trying to implement a dynamic supervisor for specific devices on a USB bus.
These devices have addresses and appear and disappear during the lifetime of the system.
For each device I need a dynamic child for my supervisor.
These children are transient, so once they crash or terminate we don't restart them (because probably they are gone then).
I have a process that scans the USB port at certain times and produces a list of all addresses of the USB devices I want to handle.
I plan to call supervisor:which_children/1 before each scan to find out which devices are present but have no child process running.
In order to find out which addresses have children running I plan to create Id atoms for the childspec that contain the addresses (there are only a few addresses possible), e.g. adr_12 if the child handles address 12.
When I try to start/restart missing children I have the somewhat ugly situation that the child specs are not automatically deleted when the transient child terminates or crashes (at least I think that it is so). So I would need code like this:
case supervisor:start_child(my_sup, Spec) of
{error, already_present} ->
supervisor:restart_child(my_sup, Spec);
Any -> Any
end
Then there is the problem that I don't know if supervisor:which_children/1 also returns already terminated children.
So it would be best if children would be deleted after they transiently terminate.
Somehow all this feels inelegant to me so I'm asking myself (and you):
How can I resolve this most elegantly?
Is it better not to use a supervisor at all in this situation?
My gut feeling/knee jerk reaction is: 'You need to use a simple_one_for_one' supervisor for them, so their spec gets removed when it stops. If you need to be able to grab a specific process for communication, I would use the gproc application for that (or an ETS table).
It sounds to me like the children you want to dynamically add to your supervisor are very similar each other. Maybe a simple-one-for-one supervisor is what you need. These supervisors are "a simplified version of the one_for_one supervisor, where all child processes are dynamically added instances of the same process.". Every child will have the same child specs, so you don't need to specify it when you call the supervisor:add_child/2.
Also, mind that the above idea of creating an atom (e.g. adr_12) dynamically could be dangerous. Atoms are limited in an Erlang system (by default ~1000000). See the documentation for details.

Resources