how to add object in NSMutableArray using macro - objective-c

for now i am creating my NSMutableArray using:
#define ARRAY_OF_ORDER_SOURCE [NSArray arrayWithObjects:DICTIONARY_OF_ORDER_SOURCE_ALL,DICTIONARY_OF_ORDER_SOURCE_ECOMMERCE,DICTIONARY_OF_ORDER_SOURCE_PHYSICAL,DICTIONARY_OF_ORDER_SOURCE_INVOICE,DICTIONARY_OF_ORDER_SOURCE_RECURRING,DICTIONARY_OF_ORDER_SOURCE_SALESVU,DICTIONARY_OF_ORDER_SOURCE_RESERVATION,nil]
i want to do some thing like:
if(somethingIstrue)
[ARRAY_OF_ORDER_SOURCE addObject:DICTIONARY_OF_ORDER_SOURCE_ALL]
if(somethingElseIstrue)
[ARRAY_OF_ORDER_SOURCE addObject:DICTIONARY_OF_ORDER_SOURCE_ECOMMERCE]
i am doing this as i need this array in my whole project, i have this in constant.h file.
how can i acheive this using macro??
Thanks.

If you really want to have a macro for this you can have a multiline macro and placed there the logic you want. It is not totally clear to me what you want to achieve but instead of macro I would prefer to have a category on NSMutableArray returning the array or some kind of Util class doing so.

There are numerous things wrong with your question. For starters, you claim you are creating an NSMutableArray, but you are in actuality creating an NSArray. You then try to addObject on the immutable array, which you cannot do.
In your line (note I modified it to add a comment):
if(somethingIstrue) {
// The NSArray isn't assigned to anything and tries to addObject to an NSArray
[ARRAY_OF_ORDER_SOURCE addObject:DICTIONARY_OF_ORDER_SOURCE_ALL]
}
you are not assigning the array to anything (as I already noted it won't work because it is trying to add to an NSArray).
I think you want to do something like:
NSMutableArray *orderedSource = [NSMutableArray array];
if (somethingIsTrue) {
[orderedSource addObject:addObject:DICTIONARY_OF_ORDER_SOURCE_ALL];
}
if (somethingElseIsTrue) {
[orderedSource addObject:addObject:DICTIONARY_OF_ORDER_SOURCE_ECOMMERCE];
}
The question you have to ask yourself is why do you insist on using a macro? You have no real design/approach here, which is why your ideas are coming across as scattered.
If you need to consistently create an array based on a set of constraints, one approach would be to create a class which can vend for you the array you want based on criteria. Or you can just do it where you need to using the approach above.

Related

Filling NSMutableArray for later use in obj-c

How do you fill a NSMutableArray with a set capacity for later use?
Basically I want to set up a NSMutableArray to act as a map for my game objects, so I have this line...
gameObjects = [[NSMutableArray alloc] initWithCapacity:mapWidth*mapHeight];
Which I had hoped would create and fill my MutableArray so I can get then access it with this kind of index...
int ii = (cellY*mapWidth)+cellX;
NSDictionary *currentObject = [gameObjects objectAtIndex:ii];
But I just learned initWithCapacity doesn't fill the array, so should I create blank objects to fill it with, or is there a Null that I can fill it with? Also would I do that with 2 for loops or is there an instruction something like "initWith:myObject" ?
I want to be able to check at a certain index within the array to see if there's an object there or not, so I need to be able to acces that index point, and I can only do that if there's something there or I get an out of bounds error.
I'll be using this NSMutableArray pretty much as a grid of objects, it's a 1 dimensional array organised as a 2 dimensional array, so I need to be able to fill it with mapWidth*mapHeight of something, and then calculate the index and do a check on that index within the array.
I've looked on here and googled but couldn't find anything like what I'm asking.
Thanks for any advice.
I think what you are looking for is [NSNull null]. It is exactly what you want- a placeholder value.
You can find more information on the topic in this question.
initWithCapacity is just a performance optimization -- it has no effect on the array behavior, it just keeps the code "under the covers" from having to repeatedly enlarge the internal array as you add more entries.
So if you want a "pre-allocated" array, you'd need to fill it with NSNull objects or some such. You can then use isKindOfClass to tell if the object is the right type, or simply == compare the entry to [NSNull null]. (Since there's only ever one NSNull object it always has the same address).
(Or you could use a C-style array of pointers with nil values for empty slots.)
But you might be better off using an NSMutableDictionary instead -- no need to pre-fill, and if the element isn't there you get a nil pointer back. For keys use a NSNumber object that corresponds to what would have been your array index.
initWithCapacity only hints to NSMutableArray that it should support this many objects. It won't actually have any objects in it until you add them. Besides, every entry in the array is a pointer to an object, not a struct like you'd normally have in a standard c array.
You need to change how you're thinking about the problem. If you don't add an object to the array, it's not in there. So either you pre-fill the array with "empty" objects as you've said, which is weird. Or you can add the objects as you need them.

Quick NSMutableArray Question

I was wondering, would using a NSMutableArray be the best way for making an array that i will be adding objects to? Or, just a regular NSArray? secondly, I'm trying to make something sort of like an ArrayList in java (so there is no limit to the size), and I would like to know how to do that. What I've thought of is to make a bigger array and copy older array into it. My code:
- (void) addAccount:(BankAccount *)b
{
accountCount = [NSNumber numberWithDouble:[accountCount doubleValue] + 1];
NSMutableArray *oldList = accounts;
accounts = [[NSMutableArray alloc] (some code to make bigger and copy over)];
}
P.S. I taught myself this language yesterday, so I may not understand you response if it's too advanced
NSMutableArrays are what you want. Also, NSMutableArrays are already like ArrayLists or STL vectors, or anything else with "no limit to the size". You can say [myArray addObject:someObject]; until you run out of memory, and it will just keep resizing itself as needed.
The difference between an NSMutableArray and an NSArray lies in the meaning of the word "mutable". i.e.: A mutable array can be modified after it's created whereas a "normal" NSArray is immutable and can't be modified after it's created.
As such, using an NSMutableArray and adding objects to it via the addObject: method would seem an ideal solution.
If you want to be adding objects all at once use NSArray. If you're going to be adding some objects now, then more later, use NSMutableArray.
Your code snippet doesn't make much sense. To make an NSMutableArray, do this:
NSMutableArray *array = [NSMutableArray array];
If you don’t need an order (normally you don’t), use a NSSet/NSMutableSet.

Using sortUsingSelector on an NSMutableArray

I have used sortUsingSelector to sort an NSMutableArray of custom objects.
Now I'm trying to sort an NSMutableArray containing NSMutableArrays of custom objects.
Can you use sortUsingSelector on an NSMutableArray, or does it only work for custom classes?
If you can use blocks, the most straightforward way using sortUsingComparator:. Otherwise, you'll need to use sortUsingFunction:.
In either case, you are going to need to write a custom block or function that takes two arrays as arguments and returns a sort order based on their contents (I'm not sure what logic you are using to determine if array A or array B is "before" or "after" the other).
You'd do something like:
static NSInteger MySorterFunc(id leftArray, id rightArray, void *context) {
... return ascending/descending/same based on leftArray vs. rightArray ...
}
Then:
[myArrayOfArrays sortUsingFunction: MySorterFunc context: NULL];
It sends the selector to the objects, so you'll need to use one of the other sorters. Probably sortUsingFunction:context:.
Of course you can also use sortUsingSelector:, it really doesn’t matter whats the object in your array as long as it responds to the selector you want to use. But NSMutableArray and NSArray don’t have any comparison methods themselves, so you’d have to extend them using a category to implement your compare method.
So you probably want to use the other sorting methods pointed out in the other answers here. It’s not impossible to use sortUsingSelector: but it is rather inconvenient and most people (including me) would argue that it’s bad style to write a category for that.

traverse Core Data object graph with added predicate?

I want to load a client object and then pull their related purchase orders based on whether they have been placed or not, purchase orders have an IsPlaced BOOL property.
So I have my client object and I can get all purchase orders like this, which is working great:
purchaseordersList =[[myclient.purchaseorders allObjects] mutableCopy];
But ideally I would actually like 2 array's - one for each order type: IsPlaced=YES and IsPlaced=NO
How do I do that here? Or do I need to do another fetch?
First, there is no reason to be turning the set into an array unless you are sorting it and there is no reason to be turning that array into a mutable array. Did you get that from some example code?
Second, you can filter an array or a set by using a predicate so you can create two sets (or arrays) easily via:
NSSet *placed = [[myclient purchaseorders] filteredSetUsingPredicate:[NSPredicate predicateWithFormat:#"isPlaced == YES"]];
NSSet *notPlaced = [[myclient purchaseorders] filteredSetUsingPredicate:[NSPredicate predicateWithFormat:#"isPlaced == YES"]];
If you are wanting to use this for a UITableView then look into a NSFetchedResultsController instead. It will save you a LOT of boiler-plate code.
Do you remember what example code you got that from? Been seeing that -mutableCopy a lot lately and would love to quash it. :)

Pass NSMutableArray object

I'm getting lost in pointer land, I believe. I've got this (code syntax might be a little off, I am not looking at the machine with this code on it...but all the pertinent details are correct):
NSMutableArray *tmp = [[NSMutableArray alloc] init];
I them pass that to a routine in another class
- (BOOL)myRoutine: (NSMutableArray *)inArray
{
// Adds items to the array -- if I break at the end of this function, the inArray variable has a count of 10
}
But when the code comes back into the calling routine, [tmp count] is 0.
I must be missing something very simple and yet very fundamental, but for the life of me I can't see it. Can anyone point out what I'm doing wrong?
EDIT: www.stray-bits.com asked if I have retained a reference to it, and I said "maybe...we tried this: NSMutableArray *tmp = [[[NSMutableArray alloc] init] retain]; not sure if that is what you mean, or if I did it right.
EDIT2: Mike McMaster and Andy -- you guys are probably right, then. I don't have the code here (it's on a colleague's machine and they have left for the day), but to fill the array with values we were doing something along the lines of using a decoder(?) object.
The purpose of this function is to open a file from the iPhone, read that file into an array (it's an array of objects that we saved in a previous run of the program). That "decoder" thing has a method that puts data into the array.
Man, I've totally butchered this. I really hope you all can follow, and thanks for the advice. We'll look more closely at it.
You don't need to call retain in this case. [[NSMutableArray alloc] init] creates the object with a retain count of 1, so it won't get released until you specifically release it.
It would be good to see more of the code. I don't think the error is in the very small amount you've posted so far..
I agree with Mike - based on the code you've posted, it looks correct. In addition to posting the code used to call the function and add items to the array, you could try checking the memory addresses of the pointer at the end of the function (when it has all of the objects), and also once it has returned (when it has no objects). I'm not sure why it would be different, but then again the items should stick in the array as well.
You need to show us a bit more of how you're adding objects to the array for us to really help.
I've seen a lot of people write code like this:
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:0];
array = [foo bar];
People doing this think it "creates and then sets" a mutable array, but that's not at all what it does. Instead, it creates a mutable array, assigns it to the variable named array, and then assigns a different mutable array to that variable.
So be sure you're not confusing the variable for the object to which it is a reference. The object isn't the variable, it's interacted with through the variable.
NSMutableArray retains objects added to it, but have you retained the array itself?
The code you posted should work. You must be doing something funny in the decoder function.
You should not retain that array. It's automatically retained with init. If you retain it, you'll leak memory. If you are just starting with objective c, take time and read "Introduction to Memory Management Programming Guide for Cocoa". It will spare you lots of headache.
Why are you writing so much code to read an array from a file? It's already supported by the framework:
+ arrayWithContentsOfFile:
Returns an array initialized from the contents of a specified file.
The specified file can be a full or
relative pathname; the file that it
names must contain a string
representation of an array, such as
that produced by the
writeToFile:atomically: method.
So you can do this:
NSMuatableArray *myArray = [NSMutableArray arrayWithContentsOfFile:#"path/to/my/file"];
This is a convenience method, so the object will autorelease. Make sure to retain this one if you want to keep it around.