Objective-c NSArray init versus initWithCapacity:0 - iphone

Do
[[NSMutableArray alloc] init];
and
[[NSMutableArray alloc] initWithCapacity:0];
compile into the exact same thing?
If they differ, then how, and which form is "better" in terms of memory and runtime performance?

No, they will not behave identically. init will create an array with some unknown but most likely nonzero capacity—whatever the authors decided was a reasonable default for most situations. initWithCapacity:0 will request an array with absolutely no allocated space. What this means is up to the NSMutableArray implementation: it might not allow a capacity of 0 and behave exactly as init, or it might not immediately allocate anything and instead allocate some amount (the same as init, possibly, or maybe not) when you first need it.
Which will perform "better" completely depends on how you expect to use the array. -init says "I have no expectations for this array; I'll either be adding to and removing from it a lot, or it will likely be pretty small." -initWithCapacity: says "I expect this array to have no more than this many elements for the foreseeable future."
About the only place where I would expect initWithCapacity:0 to be reasonable is if you are creating an array that you don't expect to fill with anything for a fairly long period of time.
Note that the standard performance caveat applies here: it's probably not an issue unless you profile and determine that it is. I can't really imagine a situation (except for thousands upon thousands of NSMutableArray objects) where the difference between these two will be substantial.

Related

Retain count of the start from 4 [duplicate]

I would like to know in what situation did you use -retainCount so far, and eventually the problems that can happen using it.
Thanks.
You should never use -retainCount, because it never tells you anything useful. The implementation of the Foundation and AppKit/UIKit frameworks is opaque; you don't know what's being retained, why it's being retained, who's retaining it, when it was retained, and so on.
For example:
You'd think that [NSNumber numberWithInt:1] would have a retainCount of 1. It doesn't. It's 2.
You'd think that #"Foo" would have a retainCount of 1. It doesn't. It's 1152921504606846975.
You'd think that [NSString stringWithString:#"Foo"] would have a retainCount of 1. It doesn't. Again, it's 1152921504606846975.
Basically, since anything can retain an object (and therefore alter its retainCount), and since you don't have the source to most of the code that runs an application, an object's retainCount is meaningless.
If you're trying to track down why an object isn't getting deallocated, use the Leaks tool in Instruments. If you're trying to track down why an object was deallocated too soon, use the Zombies tool in Instruments.
But don't use -retainCount. It's a truly worthless method.
edit
Please everyone go to http://bugreport.apple.com and request that -retainCount be deprecated. The more people that ask for it, the better.
edit #2
As an update,[NSNumber numberWithInt:1] now has a retainCount of 9223372036854775807. If your code was expecting it to be 2, your code has now broken.
NEVER!
Seriously. Just don't do it.
Just follow the Memory Management Guidelines and only release what you alloc, new or copy (or anything you called retain upon originally).
#bbum said it best here on SO, and in even more detail on his blog.
Autoreleased objects are one case where checking -retainCount is uninformative and potentially misleading. The retain count tells you nothing about how many times -autorelease has been called on an object and therefore how many time it will be released when the current autorelease pool drains.
I do find retainCounts very useful when checked using 'Instruments'.
Using the 'allocations' tool, make sure 'Record reference counts' is turned on and you can go into any object and see its retainCount history.
By pairing allocs and releases you can get a good picture of what is going on and often solve those difficult cases where something is not being released.
This has never let me down - including finding bugs in early beta releases of iOS.
Take a look at the Apple documentation on NSObject, it pretty much covers your question:
NSObject retainCount
In short, retainCount is probably useless to you unless you've implemented your own reference counting system (and I can almost guarantee you won't have).
In Apple's own words, retainCount is "typically of no value in debugging memory management issues".
Of course you should never use the retainCount method in your code, since the meaning of its value depends on how many autoreleases have been applied to the object and that is something you cannot predict. However it is very useful for debugging -- especially when you are hunting down memory leaks in code that calls methods of Appkit objects outside of the main event loop -- and it should not be deprecated.
In your effort to make your point you seriously overstated the inscrutable nature of the value. It is true that it is not always a reference count. There are some special values that are used for flags, for example to indicate that an object should never be deallocated. A number like 1152921504606846975 looks very mysterious until you write it in hex and get 0xfffffffffffffff. And 9223372036854775807 is 0x7fffffffffffffff in hex. And it really is not so surprising that someone would choose to use values like these as flags, given that it would take almost 3000 years to get a retainCount as high as the larger number, assuming you incremented the retainCount 100,000,000 times per second.
What problems can you get from using it? All it does is return the retain count of the object. I have never called it and can't think of any reason that I would. I have overridden it in singletons to make sure they aren't deallocated though.
You should not be worrying about memory leaking until your app is up and running and doing something useful.
Once it is, fire up Instruments and use the app and see if memory leaks really happen. In most cases you created an object yourself (thus you own it) and forgot to release it after you were done.
Don't try and optimize your code as you are writing it, your guesses as to what may leak memory or take too long are often wrong when you actually use the app normally.
Do try and write correct code e.g. if you create an object using alloc and such, then make sure you release it properly.
Never use the -retainCount in your code. However if you use, you will never see it returns zero. Think about why. :-)
You should never use it in your code, but it could definitely help when debugging
The examples used in Dave's post are NSNumber and NSStrings...so, if you use some other classes, such as UIViews, I'm sure you will get the correct answer(The retain count depends on the implementation, and it's predictable).

Memory management dilemma, Objective -C

I have been testing different features of Objective -C and reached topic which deals with memory management. Apparently upon reading few documents it seems memory management is a very strict in order to build well functioned application.
Now as per my understanding, When we allocate a memory an object's retainCount will become 1. However Something I wrote for learning purposes and it is giving me abnormal retainCount
It might be abnormal number for me, But people who's knows under the hood, Could you please explain how did I get this retainCount and what will be the best way to release it.
Code which has abnormal retainCount,
Object name is : ...(UISlider *) greenSender...
-(IBAction) changeGreen:(UISlider *)greenSender{
showHere.textColor = [UIColor colorWithRed:red.value green:greenSender.value blue:blue.value alpha:1.0];
NSLog(#"retainCount %d",[greenSender retainCount]);
}
Has reatainCount, just after executing my code.
A short explanation will give me a hint, And external reading resources would be appreciated.
Thanks
Do not rely on retain counts. They should only be used as a debugging tool. The reason is that if an object gets retained and autoreleased, its effective retain count has not changed, but its actual retain count has increased by one. It will be released at some point in the future when the autorelease pool drains. Therefore, you cannot rely on the retain count for knowing whether the object has been managed properly or not.
A large retain count such as 8 may indicate a programming bug (such as retaining it too many times), but it could also just be a sign that it has been retained and autoreleased a large number of times, which, although curious, could be perfectly valid.
Do not trust/rely on retainCount. Really.
From Apple:
Important: This method is typically of no value in debugging
memory management issues. Because any number of framework objects may
have retained an object in order to hold references to it, while at
the same time autorelease pools may be holding any number of deferred
releases on an object, it is very unlikely that you can get useful
information from this method.

How many Objective-C messages per second are possible on the iPhone 4?

When implementing algorithms and other things while trying to maintain reusability and separation patterns, I regularly get stuck in situations like this:
I communicate back and forth with an delegate while traversing a big graph of objects. My concern is how much all this messaging hurts, or how much I must care about Objective-C messaging overhead.
The alternative is to not separate anything and always put the individual code right into the algorithm like for example this graph traverser. But this would be nasty to maintain later and is not reusable.
So: Just to get an idea of how bad it really is: How many Objective-C messages can be sent in one second, on an iPhone 4?
Sure I could write a test but I don't want to get it biased by making every message increment a variable.
There's not really a constant number to be had. What if the phone is checking email in the background, or you have a background thread doing IO work?
The approach to take with things like this is, just do the simple thing first. Call delegates as you would, and see if performance is OK.
If it's not, then figure out how to improve things. If messaging is the overhead you could replace it with a plan C function call.
Taking the question implicitly to be "at what point do you sacrifice good design patterns for speed?", I'll add that you can eliminate many of the Objective-C costs while keeping most of the benefits of good design.
Objective-C's dynamic dispatch consults a table of some sort to map Objective-C selectors to the C-level implementations of those methods. It then performs the C function call, or drops back onto one of the backup mechanisms (eg, forwarding targets) and/or ends up throwing an exception if no such call exists. In situations where you've effectively got:
int c = 1000000;
while(c--)
{
[delegate something]; // one dynamic dispatch per loop iteration
}
(which is ridiculously artificial, but you get the point), you can instead perform:
int c = 1000000;
IMP methodToCall = [delegate methodForSelector:#selector(something)];
while(c--)
{
methodToCall(delegate, #selector(something));
// one C function call per loop iteration, and
// delegate probably doesn't know the difference
}
What you've done there is taken the dynamic part of the dispatch — the C function lookup — outside the inner loop. So you've lost many dynamic benefits. 'delegate' can't method swizzle during the loop, with the side effect that you've potentially broken key-value observing, and all of the backup mechanisms won't work. But what you've managed to do is pull the dynamic stuff out of the loop.
Since it's ugly and defeats many of the Objective-C mechanisms, I'd consider this bad practice in the general case. The main place I'd recommend it is when you have a tightly constrained class or set of classes hidden somewhere behind the facade pattern (so, you know in advance exactly who will communicate with whom and under what circumstances) and you're able to prove definitively that dynamic dispatch is costing you significantly.
For full details of the inner workings at the C level, see the Objective-C Runtime Reference. You can then cross-check that against the NSObject class reference to see where convenience methods are provided for getting some bits of information (such as the IMP I use in the example).

What makes NSdata advantageous?

I've been looking through the apple documentation for the NSdata class, and I didn't really find it too enlightening. I know how to use the class but I don't really understand the gravity of the advantages that it may or may not provide. I know its a simple question but perhaps it would be good to have such information as a reference.
Advantages over what? Certainly, it's useful to represent an arbitrary block of data as an object just as it's useful to represent a string, a number, or a value as an object. Memory management becomes simpler and is consistent with memory management for all other objects, and there are a number of useful methods defined.
Say you want to read a binary file into memory. We won't worry about the reasons why -- there are as many reasons as there are data file formats. You'll have to:
Check the size of the file
Allocate a block of memory of the proper size
Open the file
Read the contents into memory
Close the file
Remember to free the memory when you're done with it (a condition that can sometimes be tricky to detect)
(Optional) Worry about whether the block of memory has been modified
With NSData, you can just create a new instance from a path or URL and not have to think about the rest.

Asking if an object is invalid

I am trying to determine if an object is valid. The program has (at least) two threads and one of the threads might invalidate the object by removing it from an NSMutableArray. I need the other thread to check either its existence or validity before acting on it.
You can't. The only way to check if the memory your object pointer has still represents a valid object is to dereference it, but dereferencing an "invalid" object (by which I assume you mean one that has been dealloced) will result in either accessing the memory of a new object that has been allocated in the same location, garbage data that may or may not be identical to a normal object, or an unmapped memory page that will result in an immediate EXEC_BAD_ACCESS.
Any time you are holding a reference to an object you might use in the future you must retain it. If you don't you have not shown any interest or ownership in the object and the system may throw it away at any time.
Using objective C accessors and properties instead of directly setting ivars and using retain/release simplifies doing the right thing quite a bit.
Multi-threaded programming is hard. Hard does not begin to capture how difficult it is. This is the kind of hard in which a general, useable, 'reasonably qualified' way of deterministically adding two different numbers together that are being mutated and shared by multiple threads in bounded time without the use of any special assistance from the CPU in the form of atomic instructions would be a major breakthrough and the thesis of your PhD. A deity of your choice would publicly thank you for your contribution to humanity. Just for adding two numbers together. Actually, multi-threaded programming is even harder than that.
Take a look at: Technical Note TN2059
Using collection classes safely with multithreaded applications. It covers this topic in general, and outlines some of the non-obvious pitfalls that await you.
You say
I need the other thread to check either its existence or validity before acting on it.
The easiest way is to hold on to the index of the object in the NSMutableArray and then do the following
if( myObject == [myArray objectAtIndex: myObjectIndex] ) {
// everything is good !
}
else {
// my object is not what I think it is anymore
}
There are clear problem with this approach however
insertion, and deletion will stuff you up
The approach is not thread safe since the array can be changed while you are reading it
I really recomend using a different way to share this array between the two threads. Does it have to be mutable? If it doesn't then make it immutable and then you no longer have to worry about the threading issues.
If it does, then you really have to reconsider your approach. Hopefully someone can give an cocoa way of doing this in a thread safe way as I don't have the experience.