iPhone - сбой при использовании addObject в NSMutableArray - PullRequest
4 голосов
/ 04 февраля 2011

У меня проблема здесь. Или, может быть, я очень устал ...

У меня есть класс:

@interface THECLASS : UIViewController <UITableViewDelegate> {
    NSMutableArray* param;
}

@property(nonatomic, retain) NSMutableArray* param;

Внутри этого класса у меня есть метод, который вызывается, когда пользователь нажимает на UISwitch внутри tableViewCell (я встраиваю параметры в метод IBAction, который здесь не показан):

@synthesize param;

- (void) changedSelectorValue:(NSIndexPath*)indexPath isOn:(BOOL)isOn {
    [self.param addObject:@"eeeee"];
}

Это приводит к сбою приложения со следующим журналом:

2011-02-04 01:31:02.548 Learning Project[3895:207] -[__NSArrayI addObject:]: unrecognized selector sent to instance 0x630c960
2011-02-04 01:31:02.549 Learning Project[3895:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI addObject:]: unrecognized selector sent to instance 0x630c960'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00fc4be9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x011195c2 objc_exception_throw + 47
    2   CoreFoundation                      0x00fc66fb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
    3   CoreFoundation                      0x00f36366 ___forwarding___ + 966
    4   CoreFoundation                      0x00f35f22 _CF_forwarding_prep_0 + 50
    5   Learning Project                    0x00019463 -[ChoixJoursDisponibiliteController changedSelectorValue:isOn:] + 644
    6   Learning Project                    0x000190db -[ChoixJoursDisponibiliteController clickChangedSelectorValue:] + 307
    7   UIKit                               0x002f6a6e -[UIApplication sendAction:to:from:forEvent:] + 119
    8   UIKit                               0x003851b5 -[UIControl sendAction:to:forEvent:] + 67
    9   UIKit                               0x00387647 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
    10  UIKit                               0x004c9c6d -[UISwitch _onAnimationDidStop:finished:context:] + 201
    11  UIKit                               0x00327665 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 294
    12  UIKit                               0x003274f7 -[UIViewAnimationState animationDidStop:finished:] + 77
    13  QuartzCore                          0x01eab6cb _ZL23run_animation_callbacksdPv + 278
    14  QuartzCore                          0x01eab589 _ZN2CAL14timer_callbackEP16__CFRunLoopTimerPv + 157
    15  CoreFoundation                      0x00fa5fe3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19
    16  CoreFoundation                      0x00fa7594 __CFRunLoopDoTimer + 1220
    17  CoreFoundation                      0x00f03cc9 __CFRunLoopRun + 1817
    18  CoreFoundation                      0x00f03240 CFRunLoopRunSpecific + 208
    19  CoreFoundation                      0x00f03161 CFRunLoopRunInMode + 97
    20  GraphicsServices                    0x018f9268 GSEventRunModal + 217
    21  GraphicsServices                    0x018f932d GSEventRun + 115
    22  UIKit                               0x0030542e UIApplicationMain + 1160
    23  Learning Project                    0x00002580 main + 102
    24  Learning Project                    0x00002511 start + 53
    25  ???                                 0x00000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'

параметр заполняется из вида вызывающей стороны чем-то вроде:

NSMutableArray* filledArray = [NSMutableArray arrayWithObjects:@"SOME TEXT", nil] 
nextController.param = filledArray;

NSLog(@"%@", self.param); незадолго до аварии дает:

2011-02-04 02:01:17.205 Learning Project[4223:207] (
    "JOURDISPO_MARDI"
)

Почему происходит сбой? Массив есть, заполнен и не равен нулю ... Кажется, он хорошо определен ... addObject - это метод NSMutableArray ... Я не понимаю

Я не показываю его здесь, но есть тот же журнал с removeObject.

Ответы [ 5 ]

3 голосов
/ 23 ноября 2012

Ответ скрывается в комментариях к «принятому» ответу.Я пришел сюда из Google, и это исправило мою проблему, поэтому ... чтобы прояснить ситуацию, основываясь на комментарии @ e.James:

Когда вы реализуете протокол NSCopying и реализуете copyWithZone", вы НЕ ДОЛЖНЫ использовать« copy »для ваших внутренних изменяемых массивов - это НЕ копирует массив (вместо этого он создает неизменяемую копию).

например, из моего собственного кода:

// Class: MyClass

@property(nonatomic, retain) NSMutableArray* mutArray;

-(id)copyWithZone:(NSZone *)zone
{
    MyClass* other = [[MyClass alloc] init];

//  other.mutArray = [self.mutArray copy]; // WRONG!
    other.mutArray = [self.mutArray mutableCopy]; // CORRECT!

    return other;
}
2 голосов
/ 04 февраля 2011

По какой-то причине вы вызываете метод addObject: в экземпляре NSArray, как показывает трассировка стека. Возможно, синтезированный геттер вашего param объекта возвращает NSArray? Не используйте геттер в вашем методе:

- (void) changedSelectorValue:(NSIndexPath*)indexPath isOn:(BOOL)isOn {
    [param addObject:@"eeeee"];
}

В конечном итоге ошибка верна. Вы вызываете мутирующий метод для неизменяемого объекта. Как ни странно, в моем тестировании это не вызывало ошибку или предупреждение компилятора:

NSMutableArray *array = [[NSArray alloc] init];

Редактировать: Хотите ли вы в это верить или нет, каким-то образом param ivar устанавливается на экземпляр NSArray. Переопределить сеттер:

- (void)setParam:(NSMutableArray *)p {
    if (param != p) {
        [param release];
        param = [p retain];
    }
}

Затем добавьте точку останова для этого метода и проверьте, когда передается NSArray.

1 голос
/ 04 февраля 2011

Ваше свойство определено как retain, и вы говорите, что param - это «заполненный массив из представления вызывающей стороны». Это может быть вашей проблемой.

Например, если вы делаете следующее:

NSArray * filledArray = [NSArray arrayWithObjects:..., nil];
theClassInstance.param = filledArray;

Вы сохраните неизменяемый массив.

Редактировать: Чтобы отладить настройку param, вы можете сделать следующее в вашем .m:

@dynamic param;
- (NSMutableArray*)param { return param; }
- (void)setParam:(NSMutableArray*)newArray {
    NSLog(@"setting new param from class: %@",
          NSStringFromClass([newArray class]));
    [newArray retain];
    [param release];
    param = newArray;
}
0 голосов
/ 07 августа 2015

После долгих попыток я нашел решение своей проблемы.В моем случае проблема была,

У меня есть изменяемый словарь и массив

@property(strong,nonatomic)NSMutableDictionary *dictInfo;
@property(retain,nonatomic) NSMutableArray *userAccountsList;

И я добавляю список серверных массивов в массив userAccountsList, как это

 self.dictInfo = [jsonObject valueForKey:@"customerAccountList"];

Я взял другой массив и добавил список массивов серверов в этот массив

array = [self.dictInfo valueForKey:@"banker"];

и, наконец, добавил массив в userAccountsListArray следующим образом

                userAccountsList = [NSMutableArray arrayWithArray:array];

И вот добавив дополнительный объект в массив

                [userAccountsList addObject:@"Other Account"];//I was getting error here.

                [tableViewObj reloadData];

Надеюсь, это кому-нибудь поможет.Пожалуйста, проголосуйте, если это поможет.

0 голосов
/ 04 февраля 2011

Как выглядит ваш метод init? Это должно выглядеть примерно так ...

- (id)init
{
    self = [super init];

    self.param = [NSMutableArray array];

    return self;
}
...