coredata how to change default NSSet to NSMutableArray - iphone

CoreData one-to-many default to generate NSSet ,how to change NSSet to NSMutableArray?I try to change it manually,but get error:
_NSFaultingMutableSet filteredArrayUsingPredicate:]: unrecognized selector sent to instance 0x1ed35e40'

NSSet has the method allObjects, which returns an NSArray.
To get an NSMutableArray you could do this:
NSMutableArray *array = [NSMutableArray arrayWithArray:myCoreDataObject.mySet.allObjects];
Note: order is not guaranteed to be the same every time (sets aren't ordered). If order is important to you, consider an NSOrderedSet instead.
See also the docs on NSSet:
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSSet_Class/Reference/Reference.html
PS:
The reason you're getting said error:
NSSet (or _NSFaultingMutableSet for that matter) doesn't have a method called filteredArrayUsingPredicate.

Related

NSArray from NSSet of objects crashes when calling 'allObjects'

I have an core data NSSet of objects through a relationship that I am trying to put into an array.
When I call the 'allObjects' selector I get a crash on my object in the NSSet that the selector does not exist. Well, it obviously doesn't, but how do I get my data to copy into the array?
Heres the code that crashes.
NSArray *items = [surveyCategory.surveyQuestions allObjects];
Inside my surveyQuestions NSSet are SurveyQuestion objects. And this throws the error `[SurveyQuestion allObjects]: unrecognized selector sent to instance
Any ideas on how to fix this?
thanks
From the error message it looks as if surveyQuestions is not a to-many relationship
as you expect, but a to-one relationship, so that surveyCategory.surveyQuestions
is a SurveyQuestion object and not a set.
Perhaps you changed the Core Data model and did not re-create the managed object subclass
file, so that the compiler did not complain.

NSMutableArray removeObjectAtIndex

I'm getting the following error when removing from my NSMutableArray
-[__NSArrayI removeObjectAtIndex:]: unrecognized selector sent to instance 0x1cdced10
2011-07-13 00:33:14.333 MassText[1726:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI removeObjectAtIndex:]: unrecognized selector sent to instance 0x1cdced10'
However right before I remove, I print out the array and the index. Neither are nil and I have no reason to believe why this error would be happening. Any ideas?
I had this problem. Mine was that I accidentally used type casting like this.
NSMutablearray * myarray = [[NSMutableArray alloc] init];
myarray =(NSMutableArray*) [mydictionary allkeys];
This will work for some time.. but if you are in a tight and large loop this tend to fail.
I changed my code to
NSMutableArray * myarray= [[NSMutablearray alloc] initWithArray:[mydictionary allKeys]];
The object is an NSArray, not an NSMutableArray.
You are calling removeObjectAtIndex on a NSArray instance. We can see clearly by your crash log.
At this point, four smart people (not including myself) have pointed out that you're sending -removeObjectAtIndex: to an object that thinks it's an immutable array. This would be a good time to start wondering why the array is immutable when you previously thought it was mutable. If you post some code that shows how the array is created, someone here will probably be able to show you what's going wrong.
One way that you can end up with an immutable array when you thought you had a mutable one is to copy a mutable array. For example, you might have a property:
#property (copy) NSMutableArray *myArray;
Perhaps you then create a mutable array, add some objects, and assign it to your property:
NSMutableArray *tempArray = [NSMutableArray array];
[tempArray addObject:#"You say goodbye"];
[tempArray addObject:#"I say hello"];
self.myArray = tempArray;
Now, does tempArray point to a mutable array or an immutable array? I haven't tested recently, but I'm pretty sure that you get an immutable array. You definitely get an immutableArray if you say:
NSMutableArray *foo = [tempArray copy];
So, start looking for places in your code where your array pointer is reassigned. After all, if your pointer really did point to a mutable array, it'd be awfully hard to explain the exception that you're getting.
The error says that you are trying to call the removeObjectAtIndex selector on an NSArray, which won't respond to that selector.
Make sure the array is really an NSMutableArray, not an NSArray.
I had the same problem, and it was because of the use of the copy method. I made one on my own returning a NSMutableArray* and it worked.

Application crash problem in iPhone

I have used NSMutable Dictionary and NSMutable Array. The datas are to be stored and retrieved from plist(Documents Directory) using NSArray of NSMutable Dictionary.
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray removeObjectAtIndex:]: mutating method sent to immutable object'
Please Guide me why its happened?.
Thanks!
It might help if you post the exact code that causes. My guess would be that while you are using NSMutableDictionary, the call to valueForKey: returns to you a non-mutable NSArray, and you think it is returning you an NSMutableArray instance. Note that mutable arrays and dictionaries allow you to manipulate the collection of items inside them, but do not guarantee you that those items themselves are mutable. For example, if you check the Property List Programming Guide: Reading and Writing Property-List Data, you will notice the following example:
If you load the property list with
this call:
NSMutableArray * ma = [NSMutableArray arrayWithContentsOfFile:xmlFile];
ma is a mutable array with immutable
dictionaries in each element. Each key
and each value in each dictionary are
immutable.
If you need explicit control over the mutability of the objects at each level, use propertyListFromData:mutabilityOption:format:errorDescription:
You can also create an explicit NSMutableArray copy from the NSArray you got from the NSMutableDictionary.
you said you are retrieving the array as a NSArray and not casting it to a NSMutableArray before you attempt to remove an object for it. This causes an error since you can't remove an object from an NSArray
Suppose [something dictionaryValue] returns an immutable dictionary, and you want a mutable version of that dictionary. It is not enough to say:
NSMutableDictionary *d = [something dictionaryValue];
This merely tells the compiler that d is an NSMutableDictionary, but really it's the same immutable dictionary you got from [something dictionaryValue]. Instead, you need to create a new, mutable copy of the dictionary:
NSMutableDictionary *d = [NSMutableDictionary dictionaryWithDictionary:
[something dictionaryValue]];
Similarly, use [NSMutableArray arrayWithArray:...] for arrays.

NSMutableArray object thinks it is an NSArray :(

So I have a property NSMutableArray *grades. At the only place where I set this property, I am doing this:
NSMutableArray *array = [[NSMutableArray alloc] init];
self.grades = array;
[array release];
[self.grades addObject:#"20"];
The last statement generates an exception: -[NSCFArray insertObject:atIndex:]: mutating method sent to immutable object'.
What in the world am I missing?
It sounds like the property is set to copy, which means the synthesized accessor makes an immutable copy of the array
Make sure grades is a NSMutableArray.
Edit:
copy returns an immutable copy, so you can't make changes. From Apple's Objective-C docs:
Copy
If you use the copy declaration attribute, you specify that a value is copied during assignment. If you synthesize the corresponding accessor, the synthesized method uses the copy method. This is useful for attributes such as string objects where there is a possibility that the new value passed in a setter may be mutable (for example, an instance of NSMutableString) and you want to ensure that your object has its own private immutable copy. For example, if you declare a property as follows:
Although this works well for strings, it may present a problem if the attribute is a collection such as an array or a set. Typically you want such collections to be mutable, but the copy method returns an immutable version of the collection. In this situation, you have to provide your own implementation of the setter method, as illustrated in the following example.
Copying the entire collection on assignment is a heavy operation. Are you sure you don't want to retain the collection, or just assign it?
If you really want a mutable copy, then write your own setter as the docs suggest.
- (void)setGrades:(NSMutableArray *)array {
// make shallow/deep copy here, and assign to `grades`, not `self.grades`
}
What is grades declared as?
From the looks of the error message your declaring grades as an NSArray and while this is valid it does mean that you lose the mutability of the array.
To maintain the array as mutable you'll need to declare grades as an NSMutableArray as well.
edit:
In light of your edit the reason could be that your using the copy keyword in the property, this would mean that when your assigning the array using self.grades the synthesised setter method makes an immutable copy of array
self.grades probably returns an NSArray if declared as #property NSArray* grades seeing this the compiler freaks and does not want to support addObject: method. You have 2 options
cast it
like [(NSMutableArray*)self.grades
addObject:].
add the object before assigning the
array.

How to check if a NSMutableArray contains a value (null) or not?

I have an NSMutableArray instance which contains "N" number of objects and I want to check whether NSMutableArray contains a (null) or any other value.
In NSString there is a method called isEqualToString: Is there a similar method available for NSMutableArray?
Or otherwise, how can I do this?
NSMutableArray can only contain non-nil objects. Objects that print as (null) are typically nil.
The superclass method containsObject: will tell you whether a particular non-nil object is in the array. Note that this will only work if the objects are identical according to isEqual:.