RAII in an Objective-C pattern?

I find that I am writing code like this to create a safe exception code:

Container* container = [Container new]; @try { while(someCondition) { ElementType* value = [someObject createObjectFromStorage]; [container add:value]; // container retains object [value release]; } [_container release]; _container = [container retain]; } @finally { [container release]; } 

Is there any other, more concise template that follows in Objective-C?

+4
source share
2 answers

If you just want to make sure you release your objects, perhaps autorelease . You can also explore the new automatic reference counting option in Xcode 4.2.

Objective-C, generally speaking, does not lend itself to RAII, because all Objective-C objects are allocated on the heap. This means that the lifetime of the objects is not explicitly tied to any particular stack of the stack, and therefore you cannot rely on the object freed at the end of the method that allocated it.

You should also be aware that Cocoa frameworks use exceptions only to indicate a programmer error, and not expected error conditions. From Apple Exception Programming Guide :

It is important . You should reserve the use of exceptions for programming or unexpected runtime errors, such as accessing the collection outside of the scope, trying to mutate immutable objects, sending an invalid message, and losing connection to the window server. You usually take care of these types of errors with exceptions when the application is created, not at run time.

If you have existing code (such as a third-party library) that uses exceptions to handle error conditions, you can use the code as is in your Cocoa application. But you must make sure that any expected exceptions at runtime do not exit these subsystems and do not fall into the caller code. For example, a parsing library may use exceptions internally to indicate problems and provide a quick way out of a parsing state that can be deeply recursive; however, you must take care to catch such exceptions at the top level of the library and translate them into the appropriate return code or status.

In fact, since exceptions are intended to be used only in exceptional cases, by default, the newly introduced automatic reference counting will intentionally flow by objects when throwing an exception:

Cocoa's standard convention is a programmer error with exception errors and is not intended to be recovered. Providing exceptions for exceptions to code by default would impose severe restrictions on runtime and code size on code that usually does not care about the safety of exceptions. Therefore, code created using ARC throws exceptions by default, which is very good if the process is terminated immediately. Programs that take care of recovery due to an exception should enable this option.

Programming with Cocoa frames will be much better if you stick to the idioms of this structure. This means using exceptions only for programmer errors and handling expected runtime errors with NSError . Most Cocoa programmers never worry about writing code that excludes code because their code does not throw exceptions in the first place. You can succeed to follow suit.

+8
source

Abstract is a standard template.

 Container* container = [[Container new] autorelease]; while(someCondition) { ElementType* value = [someObject createObjectFromStorage]; [container add:value]; // container retains object [value release]; } [_container release]; _container = [container retain]; 

This applies only to memory management; This is not a complete replacement for RAII. Objective-C does not have a generally accepted template that completely replaces RAII, although you can create such a template in your own code base using blocks (or perhaps __attribute__((cleanup)) ).

Although we are talking about templates, by the way ... the general template is that any method that does not start with the word new , alloc , copy or mutableCopy returns an object with automatic implementation, If you change your hypothetical method to -objectFromStorage and force it follow this pattern, your cycle will be even shorter:

 while(someCondition) { [container add:[someObject objectFromStorage]]; } 
+1
source

Source: https://habr.com/ru/post/1385215/


All Articles