2

I have an object defined like this: Scores.h:

@interface Scores : NSObject {
NSString *sentenceKey;
    NSMutableArray *scorrectAnswers;
}
@property (nonatomic, copy) NSString *sentenceKey;
@property (nonatomic, copy) NSMutableArray *scorrectAnswers;
+ (id)addScore:(NSString *)senKey;

- (id)initWithSentenceKey:(NSString *)sKey  
    scorrectAnswers:(NSMutableArray *)scorrectAs;

- (id)initWithSentenceKey:(NSString *)sKey;
- (void)removeArrayObjects;

Score.m:

#import "Scores.h"
@implementation Scores

@synthesize sentenceKey, scorrectAnswers;

+ (id)addScore:(NSString *)senKey
{
Scores *newScore = [[self alloc] initWithSentenceKey:senKey
                    scorrectAnswers:[NSMutableArray new]];
return [newScore autorelease];}

I'm trying to removeAllObjects on my mutable array with this method:

- (void)removeArrayObjects;{
   [scorrectAnswers removeAllObjects];}

...which I call from another program like this:

for (Scores *sScore in scores)
{   
    [sScore removeArrayObjects];
}

... and I get this error when I run it:

-[__NSArrayI removeAllObjects]: unrecognized selector sent to instance 0x53412d0

Can anyone tell me what I'm doing wrong here? Thanks.

reid55
  • 169
  • 3
  • 14

3 Answers3

12

You are not dealing with an NSMutableArray as the error indicates you have an immutable NSArray.

This question may be your answer NSMutableArray addObject: -[__NSArrayI addObject:]: unrecognized selector sent to instance

Basically the copy you used when defining your @property will cause the setter to be generated using

scorrectAnswers = [newMutableArray copy];

which returns an immutable NSArray.

You can re-implement this method and change the previous line for:

scorrectAnswers = [newMutableArray mutableCopy];

or use retain instead of copy

This can also occur when getting data from a plist

If you are using a plist it will return an NSArray even if you save an NSMutableArray it will be cast. So when retrieving you will need to do something like:

scorrectAnswers = [[NSMutableArray alloc] initWithArray:[userDefault objectForKey:@"my_array_key"]]
Community
  • 1
  • 1
Paul.s
  • 38,494
  • 5
  • 70
  • 88
  • Thanks for your very helpful response. I am not using plist. This is how I am creating my array: [sentenceScore setScorrectAnswers:correctAnswers]; So, if I use retain instead of copy in my @property statement, do you think that will solve my problem? – reid55 Aug 24 '11 at 01:30
  • It should do but if it was your intention to take a `copy` then you should consider leaving it as `copy` but implementing the setter yourself using `mutableCopy` – Paul.s Aug 24 '11 at 01:36
1

It doesn't look like like the memory pointed to by scorrectAnswers is actually pointing to an NSMutableArray. Where and how do you initialize that variable? If you are setting the ivar directly with an autoreleased object, like:

scorrectAnswers = [NSMutableArray arrayWithCapacity:10];

then the autoreleased array will be destroyed, since you're not retaining it (or copying it). If that memory gets reallocated to point to another object, you'll see an error like the one you're getting, with an unexpected type. If the memory has not been reallocated, you'll get an EXC_BAD_ACCESS error.

Seamus Campbell
  • 17,816
  • 3
  • 52
  • 60
  • I'm not sure this is an `autorelease` issue but I did think about it because of the lack of using getters/setters – Paul.s Aug 24 '11 at 01:22
0

Similar to what was mentioned above, I had an NSMutableArray which was being re-allocated somewhere in my code as an NSArray. Once I modified that to correctly be an NSMutableArray, it resolved my problem.

I would suggest doing a quick search to ensure that you have not reallocated the array somewhere in your project and modify accordingly.

Scott D
  • 1,394
  • 1
  • 13
  • 17