我这里有问题。或者也许我真的很累......
我有一个班级:
@interface THECLASS : UIViewController <UITableViewDelegate> {
NSMutableArray* param;
}
@property(nonatomic, retain) NSMutableArray* param;
在该类中,我有一个方法,当用户点击tableViewCell中的UISwitch时调用该方法(我将params构建为一个不在这里的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'
param通过以下内容从调用者视图中填充:
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"
)
为什么会崩溃? 数组在那里,填充而不是nil ......似乎定义得很好... addObject是一个NSMutableArray方法...我不明白
我没有在这里显示,但与removeObject有相同的日志。
答案 0 :(得分:3)
答案被隐藏在对“已接受”答案的评论中。我是从谷歌来到这里的,它修复了我的问题,所以...根据@ e.James的评论更清楚:
实施“NSCopying”协议并实施时 “copyWithZone”,你不能在你的内部可变数组上使用“copy” - 这个 不要复制数组(相反,它会创建一个不可变的副本)。
e.g。来自我自己的代码:
// 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;
}
答案 1 :(得分:2)
出于某种原因,您正在addObject:
的实例上调用NSArray
方法,如堆栈跟踪所示。也许你的param
对象的合成getter返回NSArray
?不要在你的方法中使用getter:
- (void) changedSelectorValue:(NSIndexPath*)indexPath isOn:(BOOL)isOn {
[param addObject:@"eeeee"];
}
最终,错误是正确的。你在一个不可变对象上调用一个变异方法。奇怪的是,在我的测试中,这不会导致编译器错误或警告:
NSMutableArray *array = [[NSArray alloc] init];
编辑:无论您是否想要相信,param
ivar都被设置为NSArray的实例。覆盖setter:
- (void)setParam:(NSMutableArray *)p {
if (param != p) {
[param release];
param = [p retain];
}
}
然后在该方法上添加断点,并检查传入NSArray的时间。
答案 2 :(得分:1)
您的属性定义为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;
}
答案 3 :(得分:0)
你的init方法是什么样的?看起来应该是这样......
- (id)init
{
self = [super init];
self.param = [NSMutableArray array];
return self;
}
答案 4 :(得分:0)
经过艰苦的努力,我找到了解决问题的方法。就我而言,问题是,
我有一个可变字典和数组
@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];
希望它有所帮助。如果它有帮助,请投票。