initWithArray doesn't work with NSArray property - iphone

In viewDidLoad, I have:
NSArray *selectedPeople = [[selectedObject people] allObjects];
NSArray *peeps = [[NSArray alloc] initWithArray:selectedPeople];
This works just fine, but when I use an NSArray that was declared in my properties it doesn't:
NSArray *selectedPeople = [[selectedObject people] allObjects];
people = [[NSArray alloc] initWithArray:selectedPeople];
The program crashes and says that:
[People isEqualToString:]: unrecognized selector sent to instance 0x6031910
I'm using CoreData and selectedPeople holds People objects. I'm not sure what I'm missing here.

I'm pretty sure Core Data setters for a collection of objects take a set and not an array.
You could try the following:
self.people = [[NSSet setWithArray:selectedPeople];

Is people one of your properties? Did you mean to do:
self.people = [[NSArray ...
instead?

Related

Objective c add string object to an array

I've looked everywhere for this, online, on stack overflow and cannot still work out what I'm doing wrong.
I'm trying to add an element to an existing NSMutableArray. But it crashes on line 4:
-[__NSArrayI addObject:]: unrecognized selector sent to instance 0x897b320
The code:
NSMutableArray *mystr = [[NSMutableArray alloc] init];
mystr = [NSArray arrayWithObjects:#"hello",#"world",#"etc",nil];
NSString *obj = #"hiagain";
[mystr addObject:obj];
What am I doing wrong? This is driving me crazy!!!
You array is not mutable!. Use NSMutableArray
mystr = [NSMutableArray arrayWithObjects:#"hello",#"world",#"etc",nil];
You get unrecognized selector since NSArray does not contain the addObject method
Your code should be:
NSMutableArray *mystr = [[NSMutableArray alloc] initWithObjects:#"hello",#"world",#"etc",nil];
NSString *obj = #"hiagain";
[mystr addObject:obj];
The second line you're reassigning an instance of NSArray rather of NSMutableArray to your mystr variable.
Try something like this:
NSMutableArray *mystr = [NSMutableArray arrayWithObjects:#"hello",#"world",#"etc",nil];
[mystr addObject:#"hiagain"]
You originally create mystr as a mutable array, but then assign it to a standard NSArray in the next line. Instead of calling "arrayWithObjects," add each item using "addObjects" or some other function that doesn't create a new immutable array.
Ahhhhh spotted it already
Line 2 should be:
[NSMutableArray arrayWithObjects:#"hello",#"world",#"etc",nil];
Sorry to waste your time with that!

How to copy the contents of NSMutableArray to another NStArray in iphone app?

I have two array one is NSMutableArray and one is NSArray i want to store the contents of NSMutableArray in NSArray but it is not working for me gives exception unrecognised selector sent.
myArray=[[NSArray alloc] initWithArray:appDelegate.surveyAnswersScreenOne];
Note, SurveyAnswerScreenOne is an NSMutableArray
You can do that in many ways -
NSArray * myArray = [appDelegate.surveyAnswersScreenOne copy];
NSArray * myArray = [NSArray arrayWithArray:appDelegate.surveyAnswersScreenOne];
NSArray * myArray = [[NSArray alloc]initWithArray:appDelegate.surveyAnswersScreenOne];
But first of all your appDelegate.surveyAnswersScreenOne should have objects in it.
Have you made object for your appDelegate ?
appDelegate = (yourDelegateClass *)[[UIApplication sharedApplication]delegate];
If yes, then other answers should work!
myArray = [NSArray arrayWithArray:appDelegate.surveyAnswersScreenOne];
From what we see here, it is most likely that your mutable array is nil. Look into the creation of that in you app delegate. If it is created properly, check that it is retained. Is it a strong reference?
#propery(nonatomic, strong) NSMutableArray *surveyAnswersScreenOne;
for one, I would use the convenience method:
myArray = [NSArray arrayWithArray:appDelegate.surveyAnswersScreenOne];
If surveyAnswersScreenOne is a valid array, mutable or otherwise, this should work. Try printing it to the console to be sure. This will return empty array if surveyAnswersScreenOne is nil, where alloc initWithArray will fail.
Check you mutable array like this.
NSLog(#"Mutable array is %#", appDelegate.surveyAnswersScreenOne);

How to use setValue:forKey: function with NSArray

I'm try to use the functions -setValue:forKey: and get the value using -valueForKey:
Example:
NSArray *rootarr = [[NSArray alloc] init];
NSArray *array = [[NSArray alloc] initWithObjects:#"name", #"address", #"title", nil];
[rootarr setValue:array forKey:#"n"];
NSArray *getArr = [rootarr valueForKey:#"n"];
But the getArr array I got is not equal the array I set (array).
Could you please tell me what's wrong I met. And what's the way to use these functions?
NSArray's setValue:forKey: method is used for Key Value Coding, not for using an array as an associative container. You need to use NSMutableDictionary.
NSMutableDictionary *rootDict = [NSMutableDictionary dictionary];
NSArray *array = [[NSArray alloc] initWithObjects:#"name", #"address", #"title", nil];
[rootDict setValue:array forKey:#"n"];
NSArray *getArr = [rootDict valueForKey:#"n"];
An array isn't a key-value store, which you appear to want to use it as. I think you want an NSDictionary instead (or more precisely NSMutableDictionary if you want to modify it after its created).
According to the Apple documentation setValue:forKey:
Invokes setValue:forKey: on each of the array's items using the specified value and key.
Practical uses are when you want to set the same value to each element of the array
UILabel *label1 = [[UILabel alloc]init];
UILabel *label2 = [[UILabel alloc]init];
NSArray *arr = #[label1, label2];
[arr setValue:#"bye" forKey:#"text"];
NSLog(#"%# %#",label1.text, label2.text); // bye bye
in your example "getArr" is an empty array because your "rootarr" doesn't have elements, otherwise you receive a setValue:forUndefinedKey: into the contained objects that are not compliant for the assigned key
You can't add objects to an NSArray after it is created. You have to use NSMutableArray in order to do that.

How to sort an NSArray full of EKCalendars by the title

I've got a NSArray with a bunch of EKCalendar Objects in it. I need to sort them alphabetically. I'm new to selectors but I think I need something like...
NSArray *array = [otherArray sortedArrayUsingSelector:#selector('localizedCaseInsensitiveCompare:title')];
Cheers
You cannot do it that way. Instead do the following:
NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id obj1, id obj2) {
EKCalendar *cal1 = (EKCalendar *)obj1;
EKCalendar *cal2 = (EKCalendar *)obj2;
return [cal1.title localizedCaseInsensitiveCompare:cal2.title];
}];
Edit - an explanation:
-sortedArrayUsingComparator takes what is called a 'block' (an inline function) that must return an NSComparisonResult. All the hard work is done for you, as your block is run for as many pairs of objects as is needed to establish the correct order. Then all this does is cast each object type to an EKCalendar and then compare the two titles. You can adapt this to work for any type of object.
This should do the trick:
NSMutableArray *sortDescriptors = [NSMutableArray array];
NSSortDescriptor *sortByTitleAsc = [[[NSSortDescriptor alloc] initWithKey:#"title" ascending:YES] autorelease];
[sortDescriptors addObject:sortByTitleAsc];
NSArray *arraySortedByTitle = [otherArray sortedArrayUsingDescriptors:sortDescriptors];
No, you don't want to use a selector, you want to use a key path, which requires a sort descriptor. You can't append an arbitrary property name to a selector name. The selector must exactly match the method name. Otherwise you just get nothing (nil/NULL/0) for the selector.
id sortedArray = [array sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"title" ascending:YES]]];
For the sake of completeness and and timeliness, here’s the Swift 4 version:
let store = EKEventStore()
let calendars = store.calendars(for: .event)
let calendarsSorted = calendars.sorted { $0.title.localizedCaseInsensitiveCompare($1.title) == ComparisonResult.orderedAscending }
By the way, please don’t forget to request access to the store by calling store.requestAccess(to:completion:) before accessing the store’s data.

iPhone: How to access NSMutableArray two dimensional setting?

I am using insertObject for NSMutableArray for storing values into two dimensional array like below for example.
[mutableArrayPtr insertObject:[NSMutableArray arrayWithObjects:firstData, secondData,nil] atIndex:index];
I think, it is correct way of storing values in two dimensional array in Obj C.
I want to access it at later point of time. How can i do that?
Thanks!
The way you are doing it is perfectly fine. NSArray's don't have native two dimensional syntax like primitive arrays (int[][], double[][], etc.) in C do. So instead, you must nest them using an array of arrays. Here's an example of how to do that:
NSString *hello = #"Hello World";
NSMutableArray *insideArray = [[NSMutableArray alloc] initWithObjects:hello,nil];
NSMutableArray *outsideArray = [[NSMutableArray alloc] init];
[outsideArray addObject:insideArray];
// Then access it by:
NSString *retrieveString = [[outsideArray objectAtIndex:0] objectAtIndex:0];
To access your array at a later point in time, you would do something like:
NSArray* innerArray = [mutableArrayPtr objectAtIndex:0];
NSObject* someObject = [innerArray objectAtIndex:0];
Of course, change 0 to whatever index you actually need to retrieve.
EDIT:
Q: Is it "initWithObjects" (or) "insertObject:[NSMutableArray arrayWithObjects:imagePtrData,urlInStr,nil]" for two dimension?
A: initWithObjects and insertObject would both allow you to create two dimensional arrays. For example you could do:
NSMutableArray* arrayOne = [[NSMutableArray alloc] initWithObjects:[NSArray initWithObjects:#"One", #"Two", #"Three", nil], [NSArray initWithObjects:[#"Four", #"Five", #"Six", nil], nil];
// NOTE: You need to release the above array somewhere in your code to prevent a memory leak.
or:
NSMutableArray* arrayTwo = [NSMutableArray array];
[arrayTwo insertObject:[NSArray arrayWithObjects:#"One", #"Two", #"Three", nil] atIndex:0];