How do you control the release of an instance created by the instance method on the iPhone without autorun?

I'm new to iPhone development, and I ended up in the checkpoint in my understanding of memory management. I read the Cocoa Memory Management Guide and read many, many questions and answers on SO, but did not find the full answer.

If I have an instance method that creates an object, each example I saw seems to use an autorelease call:

-(NSArray *)findThings { NSArray* things = [[[NSArray alloc] init] autorelease]; // add some lovely things to my shiny new array return things; } 

Forgetting the far-fetched example, everything I read about the best iPhone examples suggests autofill pools are not recommended, but how can I implement the above example without it? If this method is called many, many times, it seems to me that I risk clogging the iPhone auto-advertising pool with "things", which seems to contradict the need to minimize resource use on such a limited platform.

I reviewed the following:

 -(NSArray *)findThings { NSArray* things = [[NSArray alloc] init]; // add some lovely things to my shiny new array [things release]; return things; } 

But then the “things” would have held the zero count until it passed to the calling method, so I feel that there is a significant risk that the object will be released between the [release] call and the method that calls findThings actually using the result.

I was a bit confused by the rule from the memory management guide that says:

Usually the received object is guaranteed to remain valid. The method was received in. (...) This method can also safely return an object to its invoker.

I was not sure if this meant as the author of the instance method, which I could safely release without risking releasing the object until the method call scope expired, or as a user of classes within the frameworks provided I could assume that I didn’t I had to worry about saving / releasing / etc for the objects I got from these classes if the method did not have a new / init / alloc / copy / whatever in its name.

So, to summarize,

  • Can I use release before returning an object instead of autorelease to avoid using the autocomplete pool on the iPhone?
  • If not, is there a better template for this that does not include an autodetection pool?
  • Did I miss something fundamental here? There seems to be a hole in the documents.

Thanks in advance

+4
source share
6 answers

Yes, you are right, autorelease pools are not recommended for iPhone development when they are not absolutely necessary. They are discouraged because it allows objects to remain in memory longer than necessary; this is a problem when developing applications for the iPhone, where there is not enough memory. Authorized objects are not deallocated until they return to the main auto-resource pool created in main.c, and this can take a long time. (If you have not created your own auto resource pool, I will be the last to talk about it.)

The case when an auto-implemented object is not needed:

 NSString *string = [NSString stringWithString:@"hello world"]; //use string 

In the first case, it’s more convenient , since I don’t have to worry about releasing string later, but it could be easily replaced:

 NSString *string = [[NSString alloc] initWithString:@"hello world"]; // use string [string release]; 

For these cases, it is recommended that you avoid the auto-implemented object.


When you return objects using autorelease is inevitable .

You should use:

 -(NSArray *)findThings { NSArray* things = [[[NSArray alloc] init] autorelease]; // add some lovely things to my shiny new array return things; } 

Since the object is invalid as soon as you call release .

 -(NSArray *)findThings { NSArray* things = [[NSArray alloc] init]; // add some lovely things to my shiny new array [things release]; // things is now in invalid object if you could potentially use things later it should be set to nil to avoid a crash things = nil; // sending messages to nil is okay, it won't cause a crash, sending messages to a released object is not okay, it can cause unpredictable crashes. return things; } 

In cases where you use a large amount of autorealized memory, you must create and merge your own autoresist pool so that the autodetection memory does not remain longer than necessary.

 -(void)useLotsOfAutoReleasedObjects { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // lots of autoreleased object // large autoreleased objects [pool drain]; // autorelease objects are released too } 

[pool pool] also releases a pool, see NSAutoreleasePool Reference for more information.

+4
source

Forgetting a far-fetched example, everything I read about the best iPhone examples suggests that auto-detection pools are not encouraged

Auto detect pools are not discouraged; they are used everywhere in Cocoa, and when used correctly, they have zero effect on memory usage. Autorelease pools are only a problem when they artificially extend the life of a large number of objects, say, in a loop, in which case you manually manage autorun pools.

+9
source

Well, autorelease to cover the exact scenarios you came across.

+3
source

You follow the Create rule .

+1
source

save yourself the hassle .. just do:

 - (NSArray *)findThings{ NSArray *things = [NSArray array]; return things; } 

as stated above, autorelease, the abstract is here to highlight the problem you have here. another solution might be that you just save it and let it go where you use it .. but it can cause a leak if you are not careful.

0
source

As everyone says, this problem is why the abstract was created.

When creating and returning objects from an instance method, the object must be automatically released before returning.

This forces the invoker to follow the correct memory management rules without taking the extra mile to make sure.

When an object from a method that does not contain the words Create, Alloc, Retain, or New is returned to the sender, then the result is expected to be auto-implemented by convention. This allows the programmer to easily know that the object should be saved if he wants to save it, or to use it safely and forget in the current area without worrying about its memory.

0
source

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


All Articles