0

I'm sorry I'm new to iOS development,this day I encountered a strange problem: when I remove object from custom object , it always return crash:

reason: '-[__NSArrayI removeLastObject]: unrecognized selector sent to instance

the following code:

@interface Base : NSObject

@property (nonatomic, assign) BOOL isFinish;
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSString *subTitle;
@property (nonatomic, strong) NSString *tagURL;
@property (nonatomic, assign) NSInteger taskScore;
@property (nonatomic, assign) BOOL inProgress;
@property (nonatomic, assign) NSInteger nowTime;
@property (nonatomic, assign) NSInteger totalTime;

@end

then I use on another class:

@property (nonatomic, strong) NSMutableArray *arr1;
@property (nonatomic, copy) NSMutableArray *arr2;    

_arr1 = [[NSMutableArray alloc] init];
for (int i = 0; i < 10; i++) {
    Base *b = [[Base alloc] init];
    b.title = [[NSString alloc] initWithFormat:@"%d", i];
    [_arr1 addObject:b];
}
self.arr2 = [_arr1 copy];// 001, I tried copy or mutable copy

[_arr2 removeLastObject]; //it always crash in here!!

So I look through some reference,some told me must conform nscopying or nsmutablecopying protocol

So I add some method in the Base class @implementation

- (id)copyWithZone:(struct _NSZone *)zone
{
    Base *copy = [[[self class] allocWithZone:zone] init];
    if (copy) {
        [copy setIsFinish:[self isFinished]];
        [copy setTitle:[self title]];
        [copy setSubTitle:[self subTitle]];
        [copy setTagURL:[self tagURL]];
        [copy setTaskScore:[self taskScore]];
        [copy setInProgress:[self inProgress]];
        [copy setNowTime:[self nowTime]];
        [copy setTotalTime:[self totalTime]];
    }
    return copy;

}

But it doesn't work , can some one help me?

0

2 Answers 2

4

First look at the error that you got. It quite clearly states that you sent "removeObject" to an NSArray which doesn't understand it, and not to an NSMutableArray. The logical conclusion is that at this point in time, _arr2 is not a mutable array but an NSArray.

Now as a software developer, you should try to think this through logically. You know the difference between copy and mutableCopy, right? You say you used mutableCopy, but what do you think happens when you set a property that is marked as "copy"? It copies. By calling copy. So you made a mutable copy of your mutable nsarray, and the property setter makes an immutable copy.

Sign up to request clarification or add additional context in comments.

3 Comments

If you (the OP) are wondering how to fix your issue - you can change '@property (nonatomic, copy) NSMutableArray *arr2;' to '@property (nonatomic, strong) NSMutableArray *arr2;', for instance. gnasher's explanation is correct.
... and return to using a mutable copy self.arr2 = [_arr1 mutableCopy];
thanks,I got it.But I'm wonder why apple not set mutableCopy property.is it to say copy property is best used when you make a immutable deep copy?
2

I think you need to use mutableCopy instead of copy. Copy will create immutable copy of the array. The removeLastObject is available on mutable version of the Array.

1 Comment

what's the best practice implementation of mutablecopyWithZone

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.