NSArray Class Method Question

Discussion in 'Mac Programming' started by Jordan72, Nov 29, 2005.

  1. macrumors member

    Here is the interesting specimen:

    + (id)arrayWithObjects:(id *)objects count:(unsigned)count
    The (id *)objects variable is what is confusing me. What is it? How do you have it set to several objects like it implies?
  2. Guest


    It means the array contains the objects. In these sorts of foundation methods it's usually a nil terminated list of objects like @"one", @"two", @"three", nil. So the objectAtIndex:1 would be @"two" (remember arrays start at index 0).

    arrayWithObjects: just puts all the objects in the array
    arrayWithObjects:count: put's only the first count objects in the list in the array so

    [NSArray arrayWithObjects: @"one", @"two", @"three", nil count:1];

    creates and array containing one object - namely the NSString @"one"
  3. macrumors 601


    It can take a c array of object pointers:
    id myObjects[10];
    int x = 0;
    for (x = 0; x < 10; x++) {
    	myObjects[x] = [NSNumber numberWithInt:x];
    NSArray *myArray = [NSArray arrayWithObjects:myObjects count:10];
    But in my experience, this method is rarely used (I have never actually had to use it in code). Usually I would use arrayWithArray: or arrayWithObjects: instead.
  4. Guest


    Same here. Never used the 'count:' variant but have used the others loads of times.
  5. macrumors member

    Excellent. Now, the thing I thought NSArray wasn't capable doing is possible: Initializing an NSArray with specific objects without having to know the names of the instances at runtime. Which seems to be required by the following code:

    + (id)arrayWithObjects:(id)firstObj, ...
    At times although, I may not know the size of an array or the objects that will go in it until runtime, which makes such a method useless, so I had to use an NSMutableArray.

    Thank you. Your previous example shows that types of objects that will go into an array can be decided at runtime:

    id myObjects[10];
    int x = 0;
    for (x = 0; x < 10; x++) {
            myObjects[x] = [NSNumber numberWithInt:x];
    NSArray *myArray = [NSArray arrayWithObjects:myObjects count:10];
    But, that doesn't allow the size to vary until runtime.

    Can I keep the size of objects dynamic for runtime by making it a pointer this way:

    id objects = (id*)malloc(p_size * sizeof(id));
    And, then use (id *)objects, as an argument with the method below?

    + (id)arrayWithObjects:(id *)objects count:(unsigned)count
  6. Moderator emeritus


    Eww, I think you're thinking too hard. Why not just use NSMutableArray? :)
  7. macrumors member

    I knew that was comming kainjow. Yes, NSMutable array handles the situation with dynamically choosing size and type at runtime.

    But, let me tell you what threw me off.

    From all that I've read in Objective-C and Cocoa texts, two main things stuck in my head with NSArray and NSMutableArray: If you only need a static array, then create a NSArray. If you need an array that is dynamic, then create a NSMutableArray. Why? It's more efficient.

    I took that seriously and this is what happened. I needed a static array, but I didn't know the type or size until runtime.

    It seems that creating a NSMutableArray just so I could handle the dynamic type and size issue and then copy it into a NSArray seemed inefficient.

    Because the implementtion is hidden with these two NS classes I have to ask. If I create a NSMutableArray, but only initialize it's size once, will it be just as efficient as a NSArray?
  8. Moderator emeritus


    It depends what you're doing. If you're doing abazillion calculations a second, then obviously you'll want to optimize and use NSArray, but even then I'm not sure NSArray is more efficient then NSMutableArray if the only time you're changing it is when you create it. Accessing elements from an NSMutableArray would not be any slower/less efficient then from an NSArray. Why would it? Unless you're really doing complex stuff, I think you're over optimizing.
  9. macrumors member

    It seems the same amount of pointer would make it as efficient.

    But, I'm thinking the added ability to be mutable adds data to each NSMutableArray field data. This in turn may affect the amount of operations a processor must do in some circumstances. I.e., when the object is created, more variables must be made. When an object's field data is copied, more field may be operated on that is unnecessary. Same with encoding, etc.

    Maybe I am being overly optimized, but really I'm being intentional. I'm hoping it may pay off one day if only a small margin of performance is the deciding factor in whether my product is chosen over another.
  10. macrumors 68030


    Premature optimization is the root of all evil :p

    First make it work, then make it work right, then profile (using Shark, Sampler, etc...), *then* make it fast.

    Also, one way would be to make an NSMutableArray and then use -copy to make a non-mutable copy of it. You lose some time on the initial creation in exchange for it being a tiny bit faster later.
  11. macrumors member

    Thanks for the advice.
  12. macrumors 603


    The only area I can think of where an mutable array might be inefficient is if you don't create it with a reasonable initial capacity, it'll be constantly resizing as you add objects to it.

    If you have any idea of how large the array is likely to be, even a rough estimate (it'll still resize if it needs to grow larger), then you should consider initialising it with that capacity - assuming the array's memory usage isn't a limitation in your example.
  13. macrumors 6502a


    I concur. I have "Make it, make it work, make it fast" written on the wall of my office after one of my employees spent an entire day on premature optimisation. :)

    NSMutableArray seems to be the best idea in these circumstances. It is not an order of magnitude slower, more like 3 messages slower when creating and a little more memory. On today's machines that is nothing.
  14. macrumors member

    I do understand what you all are saying here, but this seems like more of a bandwagon argument, so I'll retort in fun...

    So, when Unix was being developed, do you think that should have been the attitude? Because you know, the band wagon attitude seems to be leading where Microsoft and the old Macintosh OS led. Hurry, don't worry. And look where they are now. Mocking Unix. Which of course is a good and fine thing. Why? They can take leadership from the creaters that did take their time optimizing the concept to virtual perfection.:) :p :D
  15. macrumors 68030


    I realize you're just playing devils advocate here, but I think it warrants a serious response: Much of what we think of as "unix" is the result of MANY layers of additions by various folks. BSD being responsible for a lot of interesting additions (yes, THIS bsd, http://catb.org/~esr/jargon/html/B/Berkeley-Quality-Software.html ), and Linux, Solaris, HPUX, AIX, etc... adding more. These days some parts of the "standard unix" are positively awful; X11, for example. My point is that the original unix was not wildly successful due to being perfect (it's nowhere close). It was successful due to being cheap, cross platform, and easy to get; the fact that it also had some brilliant ideas (the everything-is-a-file model, and writing an OS in a portable language, for example) is just a bonus.

    Another handy jargon file reference: http://catb.org/~esr/jargon/html/U/Unix.html

    Also, down the road of the perfectionist lies this... http://en.wikipedia.org/wiki/Copland
  16. Guest


    Also it's interesting to note that Mac OS X adopted the 'Make it, make it work then make it work fast' methodology. One could still argue a case that the last stage is still a work in progress:rolleyes:
  17. macrumors member

    Thank guys for the good natured argumentation. I appretiate that. You've inspired me to start another thread, we've sort of veer into the realm of Off Topic.
  18. macrumors member

    Unix Backdoor: Are our Mac's safe with Unix?

    deleted. Ooops.

Share This Page