creating an array of NSObject classes - objective-c

I have a NSObject class in which I am sending a NSDictionary object too, the class object then sets all the entries in the NSDictionary to their native types that are variables in the NSObject class.
I would then like to pass this NSObject class into its own NSMutableArray however my app is crashing when this happens.
below is the code calling the NSObject Class and then trying to set it into a NSMutableArray.
NSArray *filteredArray = parsedDataArrayOfDictionaries; //dictionary entries are currently in nsstring format
SearchResultList *searchResultList = [[SearchResultList alloc]init];
NSMutableArray *testArray = [[NSMutableArray alloc] init];
int myCount = 0;
while (myCount <= [filteredArray count]) {
//call class and pass current NSDictionary in array[myCount]
[searchResultList assignSearchData:filteredArray[myCount]];
searchResultList = (SearchResultList*)[testingDic objectForKey:#"myObject"];
testArray[myCount] = searchResultList; //create array of nsobjectclassed, this is also where the app fails
NSLog(#"%#", testArray[myCount]);
}
Hopefully this is making some sense, I am getting abit lost in the middle of the while statements... I know I need to get back the NSObject Class then assign it to an array.. but im just not sure how to do this, any help would be greatly appreciated.

You are exceeding the size of the array filteredArray
while (myCount <= [filteredArray count]) {
should read
while (myCount <[filteredArray count]) {
as the count of an array is one higher than the last object's index, as the indices starts at 0.
honestly I am not sure, what you are trying to achieve, but you should consider to use fast enumeration instead of the while statement
for (id obj in filteredArray) {
or even fancier block-based enumeration
NSMutableArray *testArray = [[NSMutableArray alloc] init];
[filteredArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
//...
[testArray addObject:obj];
}];

Try using NSMutableArray addObject. There is no 'C' style [] operator for NSMutableArray.

Related

Sorting an array with each element contains an NSString and an NSNumber (double) entry

I created a NSMutableArray with two elements; the name of a city (string at index 0) and the distance (double at index 1) from my present position.
for (i=0;i<[City count];++i)
{
distanceFromMe = [Location distanceFromLocation:[cityLocation]];
[a addObject:[cityNames objectatIndex:i]];
[a addObject:#(distanceFromMe)]
[cityArray addObject:a]
}
"Chicago", 560.34
"New York", 204.3456
"Syracuse", 50.04
I would like to sort this array by ascending distances.
"Syracuse", 50.04
"New York", 204.3456
"Chicago", 560.34
I used:
[cityArray sortUsingDescriptors:#[ [NSSortDescriptor sortDescriptorWithKey:nil ascending:YES] ]];
But I keep getting an error of an unrecognized selector sent to instance.
In my reading it appears that the method does not need a key since there is only one NSNumber in the array element. I've read a number of different threads on this but none seem to apply.
Any help would be appreciated. Using xcode obj-c not swift.
I'd do it without using a sort descriptor.
[cityArray sortUsingComparator:
^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
NSArray* arr1 = obj1;
NSArray* arr2 = obj2;
return [arr1[1] compare: arr2[1]];
}];
While #JWWalker's solution works, I'd suggest modeling this a little bit differently.
Specifically, create a class to hold the city/distance pairs:
#interface CityDistance
#property(copy) NSString *name;
#property(copy) NSNumber *distance;
#end
#implementation CityDistance
#end
Store each of your city/distance pairs.
CityDistance *cityDistance = [[CityDistance alloc] init];
cityDistance.name = #"New York";
cityDistance.distance = #(560.3);
NSMutableArray <CityDistance *>*cities = [NSMutableArray array];
[cities addObject: cityDistance];
This allows the compiler to do more type checking, you can hang business logic off the class (i.e. maybe a -(NSNumber *)distanceFromCity:(CityDistance *)otherCity; method?), it is less fragile (oops! Forgot to add the distance to my ambiguous array!) and makes the sorting code more clear:
[cityArray sortUsingComparator:
^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
CityDistance* city1 = obj1;
CityDistance* city2 = obj2;
return [city1.name compare: city2.name];
}];

Create a dynamic array

I am new. It's a basic question i guess.
Suppose I need to have a dynamic array to store several objects from my Own class,like classA. I ve no idea about how to wrap these classA-objects and put 'em into the array, maybe NSMutableArray. thx alot.
#interface classA
{
int x;
int y;
}
...
classA *a,*b,*c;
Initialize your array with :
NSMutableArray *myArray = [[NSMutableArray alloc] init];
And then add an object with :
[myArray addObject:a];
[myArray addObject:b];
And so on
You can find it all explained here : https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/Reference/Reference.html
If you need your array to be mutable,
NSMutableArray *arr = [NSMutableArray arrayWithCapacity:2];
[arr addObject:a];
[arr addObject:b];
will suffice. Objective-C, like Smalltalk, uses dynamic typing. You can just add the objects.
If you do not need to mutate your array,
NSArray *arr = #[a, b];

My array of NSDictionaries returns the dictionaries with ONLY the keys and no values. How can I fix this?

I have an array of NSDictionaries. Right now this array only contains two dictionaries for simplicity.
As I am stepping through the code, each NSDictionary is created properly and contains the expected values... I access this array (which is filled in my model) through:
#property (nonatomic, retain) NSMutableArray *sDictionaries;
I access this property in my controller through:
NSArray *array = [[NSArray alloc]initWithArray:sLocator.sDictionaries] but when I take a look inside array, it only contains the keys and not the values (which I already saw while the dictionary was created in my model).
Any help in passing this array of NSDictionary objects from my model to my controller is greatly appreciated!
EDIT: Here is the code where I iterate through some received data and place it in NSDictionary objects.
NSMutableArray *arrayOfObjects = [[NSMutableArray alloc]initWithCapacity:0];
sDictionaries = [[NSMutableArray alloc]initWithCapacity:0];
int i = 0;
//iterate through each element, get the string, then add to the array
//I know for this example I am receiving 10 element objects which are NSStrings.
//The first string is the key of the dictionary and the next 4 strings are the values.
//Then all the objects are removed from arrayOfObjects and a new dictionary is made
for(Element *element in nodes)
{
[mArray addObject:[element content]];
if(i%5 != 0)
{
[arrayOfObjects addObject:[element content]];
}
if(i%5 == 0)
{
[idArray addObject:[element content]];
}
if([arrayOfObjects count] >= 4)
{
//Here is where the dictionary is created then added to the array.
NSDictionary *dictionary = [NSDictionary dictionaryWithObject:arrayOfObjects forKey:[idArray lastObject]];
[sDictionaries addObject:dictionary];
[arrayOfObjects removeAllObjects];
}
i++;
}
I think this line sucks.
NSDictionary *dictionary = [NSDictionary dictionaryWithObject:arrayOfObjects forKey:[idArray lastObject]];
You removed allObjects by removeAllObjects after add it to the dictionary, so the object it self is removed. Try to change that line to
NSDictionary *dictionary = [NSDictionary dictionaryWithObject:[NSArray arrayWithArray:arrayOfObjects] forKey:[idArray lastObject]];

splitting nsstring and putting into tableview

I am trying to split the string into parts and insert into a table how should i do it?
I got an error for splitting of the array which is: -[__NSArrayI componentsSeparatedByString:]: unrecognized selector sent to instance 0x7a421e0
NSArray *BusRoute = alightDesc;
int i;
int count = [BusRoute count];
for (i = 0; i < count; i++)
{
NSDictionary *dic = [BusRoute objectAtIndex: i];
NSDictionary *STEPS = [dic valueForKey:#"STEPS"];
NSString *AlightDesc = [STEPS valueForKey:#"AlightDesc"];
NSLog(#"AlightDesc = %#", AlightDesc);
NSArray *aDescArray = [AlightDesc componentsSeparatedByString:#","];
NSLog(#"aDescArray = %#", aDescArray);
}
This is the string which I'm splitting, i got it from the NSLog
AlightDesc = (
"Block1",
"Block2",
"Block3"
)
please help I'm stuck thanks.
Objective C is not a strongly typed language. All you know for sure about [STEPS valueForKey:#"AlightDesc"] is that it will return an object (of type id). When you wrote NSString *AlightDesc = [STEPS valueForKey:#"AlightDesc"] the compiler did not complain because NSString * is a valid object type. Unfortunately there is a logic error in your code so that what was actually stored under the key #"AlightDesc" is an NSArray. As others have mentioned, NSArray does not respond to componentsSeparatedByString: so you get an error at runtime.
The easy fix for this is to correct your logic: Either store an NSString in the first place or treat what you get out as an NSArray. As #janusfidel mentioned you can use an NSArray perfectly well in a table by using objectAtIndex: to get the string for the entry you want.
In some more complicated cases you may not know what you will be getting out of a dictionary for a particular key. In that case in Objective C you can just ask the object:
id anObject = [STEPS valueForKey:#"AlightDesc"];
if ([anObject isKindOfClass:[NSString class]]) {
NSString *aString = (NSString *)anObject;
// Treat as a string ...
} else if ([anObject isKindOfClass:[NSString class]]) {
// Object is an array ...
Your NSString *AlightDesc should look like this
NSString *AlightDesc = "Block1,Block2,Block3";
NSArray *aDescArray = [AlightDesc componentsSeparatedByString:#","];
If your string is what you say it is
AlightDesc = ("Block1","Block2","Block3");
then your string is the problem because it's already broken up.

NSArray filled with bool

I am trying to create an NSArray of bool values. How many I do this please?
NSArray *array = [[NSArray alloc] init];
array[0] = YES;
this does not work for me.
Thanks
NSArrays are not c-arrays. You cant access the values of an NSArray with array[foo];
But you can use c type arrays inside objective-C without problems.
The Objective-C approach would be:
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:[NSNumber numberWithBool:YES]];
//or
[array addObject:#(NO)];
...
BOOL b = [[array objectAtIndex:0] boolValue];
....
[array release];
EDIT: New versions of clang, the now standard compiler for objective-c, understand Object subscripting. When you use a new version of clang you will be able to use array[0] = #YES
Seems like you've confused c array with objc NSArray. NSArray is more like a list in Java, into which you can add objects, but not values like NSInteger, BOOL, double etc. If you wish to store such values in an NSArray, you first need to create a mutable array:
NSMutableArray* array = [[NSMutableArray alloc] init];
And then add proper object to it (in this case we'll use NSNumber to store your BOOL value):
[array addObject:[NSNumber numberWithBool:yourBoolValue]];
And that's pretty much it! If you wish to access the bool value, just call:
BOOL yourBoolValue = [[array objectAtIndex:0] boolValue];
Cheers,
Pawel
Use [NSNumber numberWithBool: YES] to get an object you can put in the collection.