GenericException : Collection was mutated while being enumerated - ios

I have searched for this problem and I know it is caused because an array is manipulated while its enumeration. Earlier in my code, I was using :
-(BOOL)busy
{
for(DataRequest* request in self.active)
if(!request.invisible)
return YES;
return NO;
}
and -(BOOL)busy is being called very frequently as the data loads from the server. Also in my code I have some lines which adds and removes objects in self.active. And because of this I was getting the exception. Then I made a change in the code as:
-(BOOL)busy
{
self.tempActive = self.active;
for(DataRequest* request in _tempActive)
if(!request.invisible)
return YES;
return NO;
}
but I am still getting the same exception. What am I doing wrong, any ideas? This is the only code where self.tempActive is used.
The exception I am getting is:
*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x9ec8f60> was mutated while being enumerated.'

You need to understand the difference between classes and stack objects (like ints and things). Setting something equal to something else does not make a copy of it if it is a class. You need to use [self.active copy] instead.

Related

NSRangeException when change dataSource

I have UITableView which dataSource change by selecting UISegmentControl's segment. It has only 2 segments and for both states I load data asynchronously first time into 2 different arrays "firstTypeNotificationsArray" and "secondTypeNotificationsArray". The main array is dataSource for UITableVIew which has data from one of arrays each time and it named "allNotificationsArray".
Change main dataSource data method
-(void)changeNotificationsByType:(BOOL)firstType{
[allNotificationsArray removeAllObjects];
if(firstType){
[allNotificationsArray addObjectsFromArray:firstTypeNotificationsArray];
} else {
[allNotificationsArray addObjectsFromArray:secondTypeNotificationsArray];
}
[notificationsTable reloadSections:[NSIndexSet indexSetWithIndex:0]
withRowAnimation:UITableViewRowAnimationFade];
}
Before call method changeNotificationsByType I check my arrays count to be !=0 but I get an NSRangeException after calling.
numberOfRowsInSection method
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return allNotificationsArray.count;
}
I tried to call reloadSections in main thread with dispatch_async but it didn't help. I've also tried to do reloadData instead and no result.
Here is a crash log:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 60 beyond bounds [0 .. 0]'
*** First throw call stack:
(0x265ec87b 0x3832adff 0x26502633 0xfcb9f 0x196879 0x3ee4a5 0x1a9dd17 0x1a9dd03 0x1aa27c9 0x265af555 0x265ada4f 0x26500129 0x264fff1d 0x2fac7af9 0x2a9889bd 0x10cc6d 0x38a78873)
libc++abi.dylib: terminating with uncaught exception of type NSException
This crash raise after switching UISegmentControl and calling changeNotificationsByType respectively. All arrays are not empty at this moment and I can't understand why my app is crashing.

selector syntax: why I am getting unrecognized selector error?

I have a method to compare 2 objects:
- (NSComparisonResult)compare:(NSObject *)object1 to:(NSObject *)object2{
// do some stuff
return NSOrderedSame; // or NSOrderedAscending or NSOrderedDescending
}
This method gets called like this:
NSArray *sortedSyncedAufgaben = [syncedAufgabe sortedArrayUsingSelector:#selector(compare:to:)];
Now, when I run this on my iPhone, a "unrecognized selector error" is thrown in the line with the selector:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ImpfVorgang compare:to:]: unrecognized selector sent to instance 0x14ebf040'
What is wrong? I thought for each parameter I need a colon?
sortedArrayUsingSelector: tries to apply you selector to the object on the left-hand side of the comparison, not to the class that calls sortedArrayUsingSelector:. In other words, if the selector exists in your class that initiates the sort, not in the class of the object inside NSArray (i.e. not in your ImpfVorgang class), you are going to see an "unrecognized selector error".
You can change your code to apply the selector manually, like this:
NSArray * sortedSyncedAufgaben = [syncedAufgabe sortedArrayUsingComparator:^(NSObject *a, NSObject* b) {
return [self compare:a to:b];
}];
Alternatively, you could move the comparison logic into the comparator block, and drop the compare:to: method altogether.

Not casting properly?

I'm following this tutorial. And I keep getting this casting error. I've imported the Obstacle.h file in the shown class (MainScene.m). I have no idea what I'm doing wrong
- (void)spawnNewObstacle {
CCNode *previousObstacle = [_obstacles lastObject];
CGFloat previousObstacleXPosition = previousObstacle.position.x;
if (!previousObstacle) {
// this is the first obstacle
previousObstacleXPosition = firstObstaclePosition;
}
Obstacle *obstacle = (Obstacle *)[CCBReader load:#"Obstacle"];
obstacle.position = ccp(previousObstacleXPosition + distanceBetweenObstacles, 0);
[obstacle setUpRandomPosition];
[_physicsNode addChild:obstacle];
[_obstacles addObject:obstacle];
}
Error:
-[CCNode setUpRandomPosition]: unrecognized selector sent to instance 0x9a88a30
2014-04-20 10:51:28.046 FlappyFlyl[2104:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CCNode setUpRandomPosition]: unrecognized selector sent to instance 0x9a88a30'
Likely you didn't set the custom class of your root node in "Obstacle.ccb" in SpriteBuilder correctly. That's why your "Obstacle.ccb" root node is a CCNode and not an Obstacle object.
The obstacle variable does not hold an object of type Obstacle. Instead it holds an object of type CCNode. CCNode does not have a method named -setUpRandomPosition, so you get a runtime error. In Objective-C, casting is a no-op. It doesn't do anything except helping the reader of your code see the intent of the person who wrote the code.
In this regard Objective-C differs from languages like C++ or Java. Objective-C has an object system that is similar to the programming language "Smalltalk".

xcode crashing for using Key I never called

So my application is crashing here:
- (void)showMenu
{
MenuViewController *menuVC = [[MenuViewController alloc] initWithStyle:UITableViewStylePlain];
NSLog(#"between the two things");
[self.navigationController pushViewController:menuVC animated:YES];
NSLog(#"after it was pushed");
}
The first NSLog works, but the second doesn't. I have an identical showSettings function so the error is supposedly in MenuViewController. The error I am getting says:
2013-09-22 02:12:05.308 Mhacks[13947:c07] *** Terminating app due to uncaught exception'
NSUnknownKeyException', reason: '[<MenuViewController 0xc3c6600> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key rearTableView.']
*** First throw call stack:
(0x1c98012 0x10d5e7e 0x1d20fb1 0xb81e41 0xb035f8 0xb030e7 0xb2db58 0x237019 0x10e9663 0x1c9345a 0x235b1c 0xfa7e7 0xfadc8 0x24928e 0xfaff8 0xfb232 0xfb4da 0x1128e5 0x1129cb 0x112c76 0x112d71 0x11389b 0x113e93 0x113a88 0x28c3 0x10e9705 0x1d2c0 0x1d258 0xde021 0xde57f 0xdd6e8 0x4ccef 0x4cf02 0x2ad4a 0x1c698 0x1bf3df9 0x1bf3ad0 0x1c0dbf5 0x1c0d962 0x1c3ebb6 0x1c3df44 0x1c3de1b 0x1bf27e3 0x1bf2668 0x19ffc 0x1d0d 0x1c35 0x1)
libc++abi.dylib: terminate called throwing an exception
I have searched the project and "rearTableView" isn't used anywhere (I used it at some point but I deleted that class and everything that had to do with it)
I've also Cleaned my project multiple times. Does anyone have any idea what's going on? Thanks!
You likely still have a reference to rearTableView in a nib. Open the relevant nib, select File's Owner, and check the Connections inspector. If you see rearTableView there, remove it with the x button.

Connect to an IOS IBAction which is not at a "valid connection destination"

I have been spending days to make connection from a button on the storyboard to a new NSObject class in an IOS project. Methods I used in OS X no longer work in IOS.
I have no trouble connection the button to the IBAction on the original UIViewController class. According to the Apple documentation my new class is not a "valid connection destination".
To work around the issue I tried to call the method in the new class from the UIViewController class. I tried notification and delegate schemes, using the posts on Stack Overflow, but could not get them to work.
The closest I came linking to a +method in the target class, such as
+ (void) startToneGenerator
{
NSLog(#"Arrived in startToneGenerator");
// [self startPlay:nil];
}
However, from inside that method I can not call the -startPlay in the same class. Because the -StartPlay class is part of an audio unit construct I can not change it to a +starPlay class without breaking the audio unit.
Can anyone point me to some documentation which describes what "valid connection destination" really means, and how to make the attempted connection a valid one.
I used the method suggested in answer 1 in OS X, where it does work, but it no longer works in IOS.
I am restating the code you clarify the problem.
// code in VC
- (IBAction)RunPauseStop:(id)sender
{
NSLog(#"arrived in RunPauseSTop"); // OK
[uToneGenerator testMethod]; // OK
// [uToneGenerator startPlay:self]; // crashes
}
// code in uToneGenerator
+ (void) testMethod
{
NSLog(#"arrived in <testMethod>"); // OK
// [uToneGenerator startPlay:nil]; // crashes
}
- (IBAction)startPlay:(id)sender
{
NSLog(#"arrived in <startPlay>"); // Don't get here
}
The line [uToneGenerator startPlay:nil]; compiles (with a warning) but crashes with:
2012-03-06 13:20:25.509 Tinnitus Tamer IP[863:f803] +[uToneGenerator startPlay:]: unrecognized selector sent to class 0x6c40
2012-03-06 13:20:25.509 Tinnitus Tamer IP[863:f803] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[uToneGenerator startPlay:]: unrecognized selector sent to class 0x6c40'
calling from testMethod; compiles but crashes with:
2012-03-06 13:22:31.413 Tinnitus Tamer IP[885:f803] +[uToneGenerator startPlay:]: unrecognized selector sent to class 0x6c44
2012-03-06 13:22:31.414 Tinnitus Tamer IP[885:f803] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[uToneGenerator startPlay:]: unrecognized selector sent to class 0x6c44'
I noted that the error message can not find +[uToneGenerator startPlay:, but the method I am trying to call is -[uToneGenerator startPlay:
uToneGenerator *utg = [[uToneGenerator alloc]init]; works OK. In spite of the compiler warning "NSProject may not respond to 'startPlay'.
Thanks for helping me out. Much appreciated. I really was stuck.
You need to call whatever class method you want inside the IBAction method in your VC:
- (IBAction)myButtonPressed:(id)sender {
[MyClass myClassMethod];
}
If you want that code to work you must declare - (IBAction)startPlay:(id)sender with a +. Otherwise you will have to make an instance of your class:
uToneGenerator *utg = [[uToneGenerator alloc]init]; //or whatever you use
and then use that to call your startPlay method:
[utg startPlay:self];
Hope it helps.

Resources