iOS struct with NSArrays - ios

I have four pieces of data I always want to keep together: 2 NSArrays and 2 ints. I thought a struct might be a good idea, but I get the "ARC does not allow objects in structs" error. What would be the best way to encapsulate the data? Using an NSDictionary?

Create a class with 4 properties. This allows for future growth by adding standard methods like isEqual: and making it work with NSCoding, etc. You can also add convenience constructors and other helpful methods as needed.

You can do it this way:
NSArray *arr1 = [[NSArray alloc] initWithObjects:#"apple",#"orange", nil];
NSArray *arr2 = [[NSArray alloc] initWithObjects:#"pine",#"pinnacle", nil];
NSInteger val1 = 1;
NSInteger val2 = 2;
NSMutableDictionary *dictTest = [[NSMutableDictionary alloc] init];
[dictTest setObject:arr1 forKey:#"arr1"];
[dictTest setObject:arr2 forKey:#"arr2"];
[dictTest setObject:[NSNumber numberWithInteger:val1] forKey:#"val1"];
[dictTest setObject:[NSNumber numberWithInteger:val2] forKey:#"val2"];

Related

NSArray alloc and init

I'm a little confused about NSArray initialization. The confusing thing is we have different init methods to init it, and if I just init it without giving any size and any objects, how compiler knows it object count or size in RAM.
What's the logic/difference behind init method? Can anybody explain it briefly?
Edit:
NSArray *sortedArray = [[NSArray alloc] init];
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"quota" ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObject:descriptor];
//How is that possible to modifying to immutable object
sortedArray = [sortedContainers sortedArrayUsingDescriptors:sortDescriptors];
I know the differences between NSArray and NSMutableArray and I'm not looking for the differences. I just wonder how that code can compile/execute without an error.
[[NSArray alloc] init] returns an empty, immutable array. There's nothing surprising about that. What else would you return from a method to mean "no items?"
how compiler knows it object count or size in RAM
The object count is 0. It's empty. Its size in RAM is the size of an empty NSArray. NSArray is an object, so it has some standard objc_object overhead, plus some instance variables for NSArray.
That said, as an implementation detail, Cocoa optimizes this out and always returns the same singleton for all empty NSArray objects. You can demonstrate this with:
NSArray *a = [[NSArray alloc] init];
NSArray *b = [[NSArray alloc] init];
NSLog(#"%p", a);
NSLog(#"%p", b);
if (a == b) { // Pointer equality, not isEqual:
NSLog(#"Same object");
}
So, what is this doing?
NSArray *sortedArray = [[NSArray alloc] init]; // (1)
// ... code that doesn't matter ...
sortedArray = [sortedContainers sortedArrayUsingDescriptors:sortDescriptors]; // (2)
At line 1, you're creating a local pointer variable, sortedArray and pointing it to an empty array (it happens to be a singleton, but that's an optimization detail).
At line 2, you create a completely different NSArray by calling sortedArrayUsingDescriptors:. You then point sortedArray at that object. ARC sees that you're no longer pointing at the empty array, and releases it. (Again, optimization details jump in here and the actual steps may be different, but the effect will be the same.)
The correct code here would be:
// ... Code that sets up sortDescriptors ...
NSArray *sortedArray = [sortedContainers sortedArrayUsingDescriptors:sortDescriptors];
Now, in very modern ObjC, you won't see [[NSArray alloc] init] written out very often. It's easier to write #[] (which is really just syntactic sugar for a method call). But before array literals were added to language, [[NSArray alloc] init] or [NSArray array] were reasonably common.
If you just init NSArray without giving any size and any objects it will remain empty during lifetime. NSArray is immutable
If your question is about NSMutableArray, read here at the SO

NSMutableDictionary giving all together same values instead of new fresh values

i am constructing All data to look like a response data dictionary from a server.
Now, newsFeedsDict1 which should Dictionary for both Bolly and Global is not only showing all data inside Global dictionary only. While my for loop is running its showing correct data for Bolly. but for 2nd time its showing Bolly's data also in Global dictionary.
if(internetStatus == NotReachable)
{
NSMutableArray *titleArr = [[NSMutableArray alloc] init];
NSMutableArray *wholeFeeds = [[[NSMutableArray alloc] init] autorelease];
[titleArr addObject:#"Bolly"];
[titleArr addObject:#"Global"];
for (NSString *title in titleArr) {
//titleArr = [[NSUserDefaults standardUserDefaults] objectForKey:#"TitleArray"];
NSLog(#"TITle arr %#",titleArr);
NSLog(#"No internet");
OrderedDictionary *newsFeedsDict1 = [[[OrderedDictionary alloc] init] autorelease];
NSMutableDictionary *newsFeedsDict = [[[NSMutableDictionary alloc] init] autorelease];
NSMutableArray *myLocalArray= [[[NSMutableArray alloc] init] autorelease];
myLocalArray = [[Database sharedDatabase] getArticleData:title];
NSMutableDictionary *articleDict = [[[NSMutableDictionary alloc] init] autorelease];
[articleDict setObject:myLocalArray forKey:#"article"];
[newsFeedsDict setObject:articleDict forKey:#"Articles"];
[newsFeedsDict setObject:title forKey:#"#name"];
[newsFeedsDict1 setObject:newsFeedsDict forKey:title];
[wholeFeeds addObject:newsFeedsDict1];
NSLog(#"news feed dict %#",newsFeedsDict1);
NSMutableDictionary *temparticleDictionary = [[NSMutableDictionary alloc] init];
self.articleDictionary = temparticleDictionary;
self.categoriesDictionary = [[NSMutableDictionary alloc] init];
self.categoriesDictionary =newsFeedsDict1;
[self createArticleDictionaryForCategory:newsFeedsDict];
}
}
It's difficult to tell what your code is supposed to do, and how you can tell that one dictionary has the same content as another. A couple problems:
NSMutableArray *myLocalArray= [[[NSMutableArray alloc] init] autorelease];
myLocalArray = [[Database sharedDatabase] getArticleData:title];
The first line is entirely unnecessary. You're creating a new array, assigning it to myLocalArray, and then assigning something else to myLocalArray. You do the same later with self.categoriesDictionary. This leads me to believe that you have some misunderstanding with respect to object pointers.
So, the array that you get from your shared database ends up at myLocalArray, and you then add that array to the dictionary at articleDict, and then add articleDict to newsFeedDict and in turn add that to newsFeedDict1. And then you log newsFeedDict1. You do exactly the same for both your titles, #"Bolly" and #"Global", so it's not at all surprising that you see the same output in both cases.
I'm having a hard time seeing why you expect the output to be different, and I have to guess that again it's due to a misunderstanding of what happens when you assign one object pointer to another. Or, perhaps you're expecting the array that you get from [[Database sharedDatabase] getArticleData:title]; to be different because you're passing in different titles. Maybe you really should be getting different arrays there; it would be a good idea to look at what happens in that -getArticleData: method and whether it really is giving you the right results for each title.
If that doesn't help, take some time to clean up your code so that it's easier for us, and more importantly, for you to really see what's going on. Also, please edit your question to give a better description of what you're seeing and how that's different from what you expect to see.
Can you write the snippet for *getArticleData()* method

What is the best way to save permanent data in one class and be able retrieve it in another class

I would like to save this array of dictionaries and be able to retrieve it another class and make decisions based upon it.
this is the array:
NSArray* cellInfoArray = [[NSArray alloc] initWithObjects:[manufacturerTextField text],[lotNumberTextField text],[expirationDateTextField text],[techniqueTextField text],[cellNumberTextField text],[rhhrProfileTextField text],[donorNumberTextField text], nil];
NSArray* keyNamingArray = [[NSArray alloc] initWithObjects:#"company",#"lot",#"expDate",#"tech",#"whichCell",#"rhTyping",#"donor", nil];
NSArray* resultsArray = [[NSArray alloc] initWithObjects:[capitalDResultLabel text],[capitalCResultLabel text],[capitalEResultLabel text],[cResultLabel text],[eResultLabel text],[fStarResultLabel text],[cwResultLabel text],[vResultLabel text],[capitalKResultLabel text],[kResultLabel text],[kpaResultLabel text],[kpbResultLabel text],[jsaResultLabel text],[jsbResultLabel text],[fyaResultLabel text],[fybResultLabel text],[jkaResultLabel text],[jkbResultLabel text],[xgaResultLabel text],[leaResultLabel text],[lebResultLabel text],[capitalSResultLabel text],[sResultLabel text],[mResultLabel text],[nResultLabel text],[p1ResultLabel text],[luaResultLabel text],[lubResultLabel text], nil];
NSArray* antigenNames = [[NSArray alloc] initWithObjects:#"D",#"C",#"E",#"c",#"e",#"f*",#"Cw",#"V",#"K",#"k",#"Kpa",#"Kpb",#"Jsa",#"Jsb",#"Fya",#"Fyb",#"Jka",#"Jkb",#"Xga",#"Lea",#"Leb",#"S",#"s",#"M",#"N",#"P1",#"Lua",#"Lub", nil];
_cellInfo = [[NSMutableDictionary alloc] initWithObjects:cellInfoArray forKeys:keyNamingArray];
_resultDictionary = [[NSMutableDictionary alloc] initWithObjects:resultsArray forKeys:antigenNames];
finalCellOne = [[NSMutableDictionary alloc] initWithObjectsAndKeys:_cellInfo,#"clerk",_resultDictionary,#"theResults", nil];
this is probably something basic, but i have been trying several things (archiver, property list, nsuserdefaults) and i keep getting "null".
the user should be able to modify the data; thus, if we use a filepath, the second class should know that too.
i dont necessarily need any code from you guys; if i get some guidance on where to focus my research to be able to do this, it would be appreciated.
Thanks guys
It sounds like a case where a singleton class would be of use to you. Application-wide access to the data and serialization/deserialization would be handled by your singleton.
#interface ApplicationData : NSObject
+ (id)sharedData;
// your class properties that expose the data
#end
#implementation ApplicationData
+ (id)sharedData {
static dispatch_once_t pred;
static ApplicationData *cSharedInstance = nil;
dispatch_once(&pred, ^{ cSharedInstance = [[self alloc] init]; });
return cSharedInstance;
}
// you'll need to provide for serialization/deserialization as you are doing now.
#end
Thereafter, your access to the shared data is via: [[ApplicationData sharedData] cellInfoArray] etc.

NSMutableArray getting changed

I have an NSMutableArray (detailsMA)having 100 strings like #"True".
Am storing that array in NSMutableDictionary which is already allocated.
NSArray *array1 = [[NSArray alloc] initWithArray:detailsMA];
[detailsDictionary setObject: array1 forKey:#"detailsMA"];
Now i changed the values of detailsMA, like replacing strings to #"False", After that am retrieving the original array values,
[detailsMA removeAllObjects];
[detailsMA addObjectsFromArray:[detailsDictionary objectForKey:#"detailsMA"]];
Here am getting modified values, not the original values.
I need original values.
Please help me.
You should copy the array.
NSArray *array1 = [[NSArray alloc] initWithArray:detailsMA copyItems:YES];
Don't forget to implement the NSCopying protocol in the classes for the objects to be copied
EDIT:
When you add the objects again, make a copy before adding.
[detailsMA addObjectsFromArray:[[NSArray alloc] initWithArray:[detailsDictionary objectForKey:#"detailsMA"] copyItems:YES]];

Anything in iPhone that resembles Android ArrayList

I am from android background and I just started working on iPhone
I want to perform this operation in iPhone as I do in Android.
ArrayList<String> aa = new ArrayList<String>();
public void fillArray(String s)
{
aa.add(s);
}
As Binyamin Sharet suggest you have to use NSMutableArray. This class allows you to create a dynamic array. You can perform addition or deletion. On the contrary NSArray is a immutable version of it. You cannot add or delete objects to a NSArray once created.
The same distinction can be applied to NSDictionary and NSMutableDictionary (and other).
Here a simple example.
NSMutableArray* arr = [[NSMutableArray alloc] init];
[arr addObject:#"first string"];
[arr addObject:#"second string"];
An important aspect of NSMutableArray (the same could be applied to other class) is the memory management one. When you add an object to a NSMutableArray it retains objects added to it. So, if you NOT use ARC you have to deal with this aspect.
NSMutableArray* arr = [[NSMutableArray alloc] init];
id obj = [[NSObject alloc] init]; // a general object
[arr addObject:obj];
[obj release];
For further info I suggest you to read about NSMutableArray class reference.
Hope it helps.

Resources