Is there anyway to get int (or float) numbers into a NSString object without using alloc and a subsequent release?
int myInt = 25;
NSString *myString = [[NSString alloc] initWithFormat:#"%d",myInt];
...
[myString release];
EDIT:
Thanks for the answers, I should have been a little more clear in the question, I am particularly interested in using this on the iPhone. As #chuck stated I could use a convenience method, but I was under the impression that I should be avoiding these where possible on the iPhone for memory / performance reasons. I could be wrong though.
gary
There's no way to create an NSString without creating it at some point. But you could use a convenience constructor so you don't have the burden of ownership.
NSString *myString = [NSString stringWithFormat:#"%d", myInt];
It will still be created and destroyed (as everything must be), but you don't have to do it yourself.
I could use a convenience method, but I was under the impression that I should be avoiding these where possible on the iPhone for memory / performance reasons.
The “performance reason” is the cost of autoreleasing an object. This was, at one time, expensive on an iPhone. (I don't know whether it still is.) The only alternative is explicitly allocating it and releasing it yourself. As others have pointed out, you can't have an object without having allocated it, and you mustn't allocate it without releasing it. You need both things to happen one way or another.
The memory reason is simply that an autoreleased object lasts longer—specifically, until the autorelease comes due. Autorelease many objects, and your memory usage will pile up; pile it up high enough, and SpringBoard will tell your app to knock it off (and/or just kill it). The solution is to make the objects not last so long, which means either (1) creating and draining your own autorelease pool around a known batch of objects or (2) managing the objects' lifetimes (that is, allocating and releasing them) yourself.
This latter reason is not specific to the iPhone—it affects the Mac as well, although our ceiling is higher: Macs have more short-term memory, plus virtual memory, so we can get away with more memory usage. Even so, we Mac programmers should also try not to waste memory, partly because paging hell wrecks one's day, and partly because we will get email from users if our apps sit too high in the Activity Monitor list.
NSString *mystring = [NSString stringWithFormat:#"Hello: %d",myint];
it should be autoreleased if you create it this way
i think the convention is that unless you see the word init or alloc in the method name then it should return an autoreleased object. i.e. the object is added to the current autorelease pool and flushed when the app advances to next stage in lifecycle
You want
NSString *aStr=[[NSNumber numberWithInt:myInt] stringValue];
It returns an autoreleased string.
You could use an NSMutableString (-appendFormat:) or a standard C-string. However, fundamentally, no, you're going to have to allocate memory somewhere.
Why not define a macro... something like
#define intString(i1) [[[NSString alloc] initWithFormat:#"%d",i1] autorelease];
put it in your prefix header.
Most of the time autorelease will have zero impact on your app's overall memory usage. You only need to be concerned with autorelease if you're accumulating many object instances. For example:
for (int i = 0; i < 1000; ++i)
{
NSString* s = [NSString stringWithFormat:#"%d", i];
...
}
That example will accumulate at least 1000 different string instances before anything is released, which is not desirable. That's a situation where you would look for alternatives.
If you wanted to avoid creating a bunch of string instances you could use NSMutableString:
NSMutableString* s = [NSMutableString stringWithCapacity:20];
[s appendFormat:#"%d", 123];
...
[s setString:#""];
[s appendFormat:#"%d", 456];
...
It's questionable whether that's any faster than simply creating and releasing separate string instances, but that pattern may fit better with what you're trying to accomplish in your code.
Related
For many classes there are initXXX methods and typeXXX methods, for example:
NSNumber *n1 = [[NSNumber alloc] initWithInt:1];
NSNumber *n2 = [NSNumber numberWithInt:1];
I've read about manual memory management and I think that I understand how those lines are different with manual memory management (second is just shortcut for autoreleased object).
But with ARC I don't understand which API I should use? Should I use only alloc-init pattern because ARC is smart enough to make value autoreleased if necessary and avoid autorelease overhead when value is only used locally? Or ARC can optimize out autorelease and corresponding overhead even when I use something like numberWithInt?
I would like to use second variant when available, because it's shorter and easier to read. But I don't want to introduce performance overhead just for this reason.
Or ARC can optimize out autorelease and corresponding overhead even when I use something like numberWithInt?
It can, even with these convenience factory (so are they called) methods. Here all is explained well.
So you can use either one.
I'm just investigating some memory leaks in my app, I'm using Xcode 4.0.2. I've run the Analyze tool in Xcode and a good few memory leaks have been identified. I'm relatively new to Objective-C, this is my first app. I've pasted the code here:
http://pastie.org/3155043
I've added comments to the above code, where the memory leaks are occuring.
Memory Leak One: Method returns an Objective-C object with a +1 retain count (owning reference).
Memory Leak Two: Object allocated on line 248 and stored in 'imagesNames' is not referenced later in this execution path and has a retain count of +1 (object leaked).
Memory Leak Three: Potential leak of an object allocated on line 246 and stored into 'cmpWordoutStr'.
Any help appreciated.
Regards,
Stephen
You might want to consider using Automatic Reference Counting in your project.
I asked a question the other day on here, as I wasn't sure that it was a good idea, but the answers convinced me that it really is a step forward and is well worth taking advantage of:
To ARC or not to ARC? What are the pros and cons?
Hope this helps :)
Leak 1) You don't show the return or identify which variable is returned, so not possible to definitively diagnose this one.
Leak 2) You alloc/init an NSString and assign it to a variable that is never released. This is wrong for two reasons:
For each alloc there must be a corresponding release somewhere.
There is no point in doing alloc/init on an empty string. If you want an empty string just use #"".
Leak 3) Basically the same as (2).
(You really need to get a good book on Objective-C programming and study and restudy the section on storage management. Otherwise you'll be stumbling around in the dark.)
You're allocating an object first
NSString *cmpWorkoutStr = [[NSString alloc] init];
and then reassign the pointer without freeing the memory:
cmpWorkoutStr = [cmpWorkoutStr stringByAppendingString:indWorkoutStr];
hence the leak.
I didn't analyze your code in depth, but I guess you actually want NSMutableString there.
As Tom Andersen suggested above I used auto release and this solved the problem, example below:
NSString *cmpWorkoutStr = [[[NSString alloc] init] autorelease];
NSString *imageNames = [[[NSString alloc] init] autorelease];
Regards,
Stephen
Let's say that I have a loop that returns a bunch of autoreleased NSData objects...
NSData* bigData = ...
while(some condition) {
NSData* smallData = [bigData subdataWithRange:...];
//process smallData
}
Under ARC, should I still wrap an #autoreleasepool around the while condition?
NSData* bigData = ...
#autoreleasepool {
while(some condition) {
NSData* smallData = [bigData subdataWithRange:...];
//process smallData
}
}
The reason why I'm asking is I see the living allocation count in instruments going through the roof for my NSData objects that invoke a dataWith... method as opposed to an initWith... method. When I use initWith..., the living allocation count is much, much less.
Is it better to prefer the initWith... methods whenever possible?
Yes you should still use autorelease pools when using convenience methods in a tight loop. All the old memory management rules still apply under ARC, the compiler is merely injecting RRs for you. Checkout the great post by the awesome Mike Ash!
Link
I think your issue is that the autorelease pool is supposed to go inside the loop. With the loop inside the autorelease block rather than vice-versa, the accumulated objects won't be released until after the loop finishes.
Under ARC, should I still wrap an #autoreleasepool around the while condition?
Yes. Autorelease Pools are still in place, and grow and pop as before. The compiler just adds and coalesces the necessary retains and releases operations when ARC is enabled (echoing Logan), based on the methods that are visible to the TU and default naming conventions.
Execution in ARC is nearly identical the manual reference counting: Autorelease pool stacks still exist. One difference is that the compiler may order the reference counting operations slightly different from the way you wrote it (not in an incorrect way), and may omit unnecessary retain cycles.
Is it better to prefer the initWith... methods whenever possible?
WRT minimizing heap growth compared to the autoreleased counterparts: Yes. That's always been the case. It's especially important on iOS devices, where memory is quite limited.
The exception to this is when the object may avoid an allocation. Example:
NSString * copy = [NSString stringWithString:arg];
in this case, copy may be [[arg retain] autorelease]. Note that in this case, copy is still autoreleased, but you should not usually go to great lengths to test the presence of such optimizations. Note: It's also better to use copy = [arg copy]...[arg release] here.
The other bonus is that your ref count imbalances are often caught earlier when the object is never autoreleased, and closer to the call site (rather than when the Autorelease Pool is finally popped).
Performance with large autorelease pools is actually much worse than most people would suppose. If you can avoid depending on them heavily (e.g. using alloc+init...+release), you can make your program noticeably faster. Explicitly creating autorelease pools is cheap, and can help minimize this problem. When allocations are large and/or numerous, avoid using autorelease on them where possible, and do wrap these sections in explicit autorelease pools.
Is there any difference performance-wise in the following 2 snippets of code?
NSString* str = [[NSString alloc] initWithFormat:#"%i", 10];
// Do something with |str|.
[str release];
NSAutorelasePool* pool = [[NSAutreleasePool alloc] init];
NSString* str = [NSString stringWithFormat:#"%i", 10];
// Do something with |str|.
[pool drain];
I see people trying to suggest using factory methods whenever possible.
Isn't it better to release objects as soon as possible rather than when a pool is drained.
I would see the first type being very efficient in certain cases such as in tight-loops.
I see people trying to suggest using
factory methods possible.
I'd guess that's because it's basically the same thing, but you don't have to remember to release the object. Some might say that using the convenience method is a little more readable, too, especially since you don't have to end every method with a sequence of -release messages.
Isn't it better to release objects as
soon as possible rather than when a
pool is drained.
You can make that case in some situations, such as inside a loop. That's often not an important consideration, though... many methods don't loop at all and only create a handful of objects.
I would see the first type being very
efficient in certain cases such as in
tight-loops.
Sure. So you should know when it is and when it isn't appropriate to autorelease objects, and you should write your code accordingly. But it doesn't follow that you should always try to avoid autoreleasing objects any more than it makes sense to always try to use convenience methods.
BTW, if you're writing loops that iterate many times, you should consider creating an autorelease pool. Chances are, you'll be using other methods inside your loop, and those methods might create autoreleased objects. Using your own pool and draining it periodically prevents those objects from piling up. If you do that, though, it takes a great deal of wind out of the the idea that you shouldn't use autoreleased objects in your loop.
Yes it is. First one is better memory management, worth it if you are doing it, like you said, in a loop to avoid allocating a lot before the next pool drain.
I'm still wrapping my head around some of the nuances of memory management in objective-C, and came up with the following case I'm unsure about:
+ (NSDecimalNumber*)factorial: (NSDecimalNumber *)l {
NSDecimalNumber *index = l;
NSDecimalNumber *running = [NSDecimalNumber one];
for (; [index intValue] > 1; index = [index decimalNumberBySubtracting:[NSDecimalNumber one]]) {
running = [running decimalNumberByMultiplyingBy: index];
}
return running;
}
Here decimalNumberByMultiplyingBy and decimalNumberBySubtracting will be creating a lot of NSDecimalNumbers, which will get autoreleased eventually as I understand it, but I worry until that time the containing program will be hanging unto an awful lot of memory.
Should I be introducing an autorelease pool somewhere? (If so where?) Is that going to have a noticeable effect on performance (when compared to the side effect of so much memory in use)?
Is autoreleasing the right mechanism to use here? Should I look at breaking the loop apart and manually releasing memory as I'm done with it?
It's likely a n00b question, but I'm trying to get a flavour for what the best practice(s) is/are in this situation.
It's good practice to avoid creating a bunch of large autoreleased objects within a single pass of the run loop. You already seem aware of the solutions. You can use non-autoreleased objects and release them when you're done with them. You can also create an autorelease pool for sections of your code that create a large number of autoreleased objects. When an object is autoreleased, it gets released when the enclosing autorelease pool is released/drained. Using an autorelease pool would look like this:
NSAutoReleasePool *subPool = [[NSAutoreleasePool alloc] init];
// Code that generates a bunch of autoreleased objects.
[subPool release];
But, before you do any optimization, run some benchmarks and see if you actually need to optimize. My guess is that the method you've shown won't cause any problems. However, let's say you're trying to apply your method to a set of a million random integers within a single loop. In that case, you might benefit from using an autorelease pool.
Check out Apple's Memory Management Programming Guide for Cocoa for more details.
You could set up an autorelease pool within the loop, but why bother?
You are not going to be able to accumulate that many objects in this loop, because you're computing factorials, and the largest exponent an NSDecimalNumber can have is 127.
You'll get an overflow error before you even get to 100 iterations through the loop.
Note that the main autorelease pool gets emptied every time the application makes a trip through the main run loop, so the autoreleased values are not going to hang around very long.
Best way to determine the answer is to write it a few different ways and test. I don't think this is going to be a problem, though, NSDecimalNumbers are going to max out around ~100!, and 100 NSDecimalNumber objects probably won't make a bit of difference.
Answer to your other questions: In situations where it will matter you can manually release your objects. You can also create an autorelease pool inside that loop. Autorelease is super fast.
while(/*condition*/) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// code goes here
[pool drain];
}