The right approach for checking memory allocation in Objective-C

I am wondering what the correct approach would be after executing a command that allocates memory in Objective-C (mostly I mean iOS apps). My dilemma stems from the fact that checking the success of an unsuccessful memory allocation operation adds a lot of lines of code, although I wonder if this is really useful. Moreover, sometimes the allocation of memory is obvious, for example, the use of "alloc", but sometimes it happens behind the scenes. And even if we check every distribution - when we find that it did not succeed - in fact we can do little. So maybe the right approach is to just let it fail and cause the application to crash? Take a look at this code:

// Explicit memory allocation NSArray a1 = [[NSArray alloc] initWithObjects:someObj, nil]; if (!a1) { // Should we make this check at all? Is there really what to do? } // Implicit memory allocation NSArray a2 = [NSArray arrayWithObjects:someObj, nil]; if (!a2) { // should we make this check at all? Is there really what to do? } 

What do you think would be the right approach? Check or not check for failures? iOS developers - how did you deal with this in your applications?

+6
memory-management ios memory objective-c iphone
source share
4 answers

With the power that you use in your Iphone / smartphone, the time taken to compute several tests is ridiculous to think “is it really worth checking”, it is always a good test and catch any failures in your code / distributions, (if you do not, this it's more like you're lazy to add a few extra lines to your code.

In addition, “allowing the application to crash” gives a REALLY bad impression on your application, the user sees the application closely for no reason and thinks about its poor quality software. You should always add your tests, and if you can’t do anything about the error, at least you should display a message before closing the application (makes the user less upset).

There are several options when tracking memory allocation, such as catch catch. if the returned pointer is zero, check the size of the list, etc.

you should think about how to start the application in case of distribution failure:

  • if this is a jsut view of your interface, display a message that does not load a specific view ...

  • If this is the main and only view, close the application with the message

...

I don’t know which application you are running on, but if you have little memory, you should consider creating a system to allocate freed memory as your progress in your application so that you always have the maximum available memory. it may be a little slower than saving caching, but the quality of your application will improve if you suppress any power.

-2
source share

Fantasy: Each memory allocation will be checked and any failure will be reported to the user in a friendly manner, the application will be closed, an error report will be sent, you can fix it and the next version would be ideal [in this case].

Reality: By the time something that is trivial, like arrayWithObjects: fails, your application was dead a long, long time ago. In this case, recovery does not occur. It is likely that the frameworks have not received the allocation and have already ruined your application state.

Also, as soon as something as basic as arrayWithObjects: failed, you still cannot tell the user. There is no way that you can reliably place the dialog on the screen without additional distributions.

However, the failure happened much further before your application removed the selection. Namely, your application should have received a warning about memory and should have responded (a) with a constant state so that user data is not lost, and (b) free up as much memory as possible to avoid a catastrophic failure.

However, a memory warning is the last viable line of defense in a memory war.

The first attack on memory reduction is the design and development process. You should consider using memory from the very beginning of the application development process, and you should optimize memory usage when polishing the application for publication. Use the Allocations Instrument (see this Heapshot analysis report I made a few back - it is very applicable) and justifies the existence of all the main memory consumers.

+11
source share

IPhone applications must register for UIApplicationDidReceiveMemoryWarningNotification notifications. iOS will send them when available memory becomes low. Google iphoneappprogrammingguide.pdf (dated 10/12/2011) for more information.

However, one general approach to the problem that I saw is to reserve a block of memory when starting the application as a "pillow". In your code, enter a test after each selection. If the distribution fails, release the cushion so that you have enough memory to display the error message and exit. The size of the pillow should be large enough to fit your fraudulent application to stop working. You can determine the size of the pillow using a memory tester.

This is a really difficult problem because it rarely happens (for well-designed programs). In the PC / mini / mainframe virtual memory, virtual memory virtually eliminates the problem, but the most pathological programs. On systems with limited memory (such as smartphones), stress testing your application using the heap monitoring tool should give you a good idea of ​​its maximum memory usage. You can code a high-watermark wrap routine that does the same.

+2
source share

Check them, cancel debugging (so that you know where / why errors exist) and click on the error to the client (in most cases). The client will usually have more context - try again with less request? somehow doesn’t work? disable the function? Displays a warning to the user, etc. Etc. The above examples are not the end of the world, and you can gracefully recover from many - in addition, you need (or should) know when and where your programs fail.

0
source share

All Articles