I was testing an app on Xcode and I got this error saying that an exception has been thrown. Using the debugger, I added an exception breakpoint which led me to this:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.navigationController.delegate = self;
int index = [[NSUserDefaults standardUserDefaults] integerForKey:#"ChecklistIndex"];
if (index != -1) {
Checklist *checklist = [self.dataModel.lists objectAtIndex:index];
[self performSegueWithIdentifier:#"ShowChecklist" sender:checklist];
}
}
With this being the highlighted line:
Checklist *checklist = [self.dataModel.lists objectAtIndex:index];
And the debugger said this:
-[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array
I'm not too sure how to fix this. If any more information is needed let me know. Thanks.
It looks like your self.dataModel.lists property is empty.
You should look at where you actually set that ".lists" property or "dataModel" property. One of them is not what you think it is.
Related
i'm trying to segue from objective-c to swift.
However when I try this using the object below I receive the following error
I don't know what i'm doing wrong, i've setup the segue on the storyboard and assigned it to the same ID, created the prepare function and the perform.
- (void)renderer:(id<SCNSceneRenderer>)renderer willRenderScene:(SCNScene *)scene atTime:(NSTimeInterval)time {
// Look for trackables, and draw on each found one.
size_t trackableCount = trackableIds.size();
for (size_t i = 0; i < trackableCount; i++) {
// NSLog(#"this is the variable value: %d", trackableIds[i]);
// Find the trackable for the given trackable ID.
ARTrackable *trackable = arController->findTrackable(trackableIds[i]);
// SCNCamera *camera = self.cameraNode.camera;
SCNNode *trackableNode = self.trackableNodes[i];
if (trackable->visible) {
if (trackableIds[i] == 0) {
NSLog(#"Starbucks");
[self performSegueWithIdentifier:#"brandSegue" sender:self];
} else if (trackableIds[i] == 1) {
NSLog(#"Dortios");
}
} else {
trackableNode.opacity = 0;
}
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"brandSegue"]) {
JSONViewController *destViewController = segue.destinationViewController;
}
}
EDIT - ERROR MESSAGE
2017-11-09 16:57:05.232992+0000 MyARApp[2573:1099927] *** Assertion failure in -[UIApplication _cachedSystemAnimationFenceCreatingIfNecessary:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3698.21.8/UIApplication.m:1707
2017-11-09 16:57:05.233169+0000 MyARApp[2573:1099927] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'accessing _cachedSystemAnimationFence requires the main thread'
*** First throw call stack:
(0x186f51d04 0x1861a0528 0x186f51bd8 0x1878e1c24 0x1905e9c4c 0x19064646c 0x190432338 0x19038fe5c 0x1903fb6a8 0x190470bf0 0x1906ffb00 0x190701434 0x190703cd8 0x19070420c 0x190703c28 0x190467ab4 0x190707ae4 0x190b38854 0x190ca6b30 0x190ca69d4 0x1906f7e18 0x1020a27cc 0x19a66c610 0x19a725a84 0x19a723e00 0x19a724d1c 0x19a5a0cc4 0x19a6717ac 0x19a671b14 0x19a671f8c 0x19a71a67c 0x19a5d24a0 0x19a6e1c90 0x1035b949c 0x1035b945c 0x1035c8110 0x1035bc9a4 0x1035c9104 0x1035d0100 0x186b7afd0 0x186b7ac20)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
After discussion in Chat and fixing various issues, I'll take them one by one:
> *** Assertion failure in -[UIApplication _cachedSystemAnimationFenceCreatingIfNecessary:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3698.21.8/UIApplication.m:1707
> *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'accessing _cachedSystemAnimationFence requires the main thread'
That's the first issue causing a crash. This is talking about an internal method of CocoaTouch needed to be called in main thread.
The issue lies on your performSegueWithIdentifier:sender:. All UI related calls have to be done in main thread.
To fix it:
dispatch_async(dispatch_get_main_queue(), ^(){
[self performSegueWithIdentifier:#"brandSegue" sender:self];
});
Fixing this revealed a second issue:
it segues but it trigger twice, do you know why this may happen?
You are doing this:
for (size_t i = 0; i < trackableCount; i++)
{
if (somethingTest)
{
[self performSegueWithIdentifier:#"brandSegue" sender:self];
}
}
Who said that in your for loop you don't valid multiple times somethingTest?
To fix it (I'm talking about the logic, I didn't do the dispatch_async(dispatch_get_main_queue(){()} part to avoid adding noise to the algorithm).
//Declare a var before the for loop
BOOL seguedNeedsToBeDone = FALSE;
for (size_t i = 0; i < trackableCount; i++)
{
if (somethingTest)
{
seguedNeedsToBeDone = TRUE;
}
}
//Perform the segue after the for loop if needed
if (seguedNeedsToBeDone)
{
[self performSegueWithIdentifier:#"brandSegue" sender:self];
}
Next issue, passing data to the Destination ViewController:
JSONViewController *destViewController = segue.destinationViewController;
destViewController.brand = #"something";
You are mixing Swift & Objective-C, since XCode was complaining about not knowing brand being a property of JSONViewController object, you needed to add #objc before the declaration of the var. More detailed answer can be found here.
Finally, a tip to pass the data of you for loop is using the sender (it's faster in term of coding than creating another var, etc.):
//Calling the performSegue with custom value to pass
[self performSegueWithIdentifier:#"brandSegue" sender:someVarToSend];
//Passing the custom value
destViewController.brand = someVarToSend;
I guess the more safe way is to use navigationController?.pushViewController(_:animated:), instead of using segues.
This is an implementation section of a class named "Model". Here I recursively call call the setDictionary method upto 3 layers, which raises an exception (NSMutablearray mutated while being enumerated) this exception can be avoided if I use for loop istead of forin, I would like to understand how this error occurs...Can any one help...Please dont reply with some links that point to some definition, I already read lots of documentation and I dont understand how the exception is raised in this situation.
#implementation Model
#synthesize arraySubOptions,boolHasSub;
- (instancetype)init
{
self = [super init];
if (self) {
boolHasSub = NO;
arraySubOptions = [NSMutableArray new];
}
return self;
}
-(void)setDictionary:(NSDictionary*)dict{
boolHasSub = [[[dict objectForKey:#"key_has_sub"] nullCheck:[NSString class]] boolValue];
if (boolHasSub) {
NSArray * arrayDict = (NSArray*)[self loadDataFromDB];
if(arrayDict && (arrayDict.count>0) ){
for (NSDictionary * dict in arrayDict) {
Model * objOption = [Model new];
[objOption setDictionary:dict];
[arraySubOptions addObject:objOption]; /*This is the line that raises the exception. It raised */
}
}
}
}
#end
Your method
[self loadDataFromDB]
should be altering your arrayDict, so, when you reach
[objOption setDictionary:dict];
is entering twice in that function, modifying your arrayDict and launching this exception.
Doing it with 'for' instead of 'foreach' works because you set the limits of your loop and it doesn't reach any exception if your limit isn't out of bounds. (i > arrayDict.count)
[self loadDataFromDB] returns an array which gets deallocated when the method call ends, since the object was created inside the method. So copying the returned array did the trick.
[[self loadDataFromDB] copy]
I am trying to create a dynamic top menu.
I have to get some data from a json request and display this data in one of the sections of the top menu. I'm new in Objective-C. I also tried with NSMutableArrays and I had an error. Only one MutableArray and I can show the top menu. I am following this third party framework for top menu “https://github.com/dopcn/DOPNavbarMenu”.
- (DOPNavbarMenu *)menu {
if (_menu == nil) {
[strArray objectAtIndex:0];
NSLog(#"Random Selection is:%#",strArray);
_menu = [[DOPNavbarMenu alloc] initWithItems:#[strArray] width:self.view.dop_width maximumNumberInRow:_numberOfItemsInRow];
_menu.backgroundColor = [UIColor blackColor];
_menu.separatarColor = [UIColor whiteColor];
_menu.delegate = self;
}
return _menu;
}
-(void)loadData
{
strResponse=[dictionary objectForKey:#"data"];
strMsg=[strResponse valueForKey:#"Text"];
NSLog(#“string message is :%#",strMsg);
NSLog(#"String Response is :%#",strResponse);
NSLog(#"Text Response is: %#",strMsg);
strArray = [[NSMutableArray alloc] init];
[strArray addObject:strMsg];
NSLog(#"Array values are - %#", strArray);
}
Array values are: Life Style,Care Plans,Trackers/Diaries,Questionnaires/Assessments.
but i got exception like this:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]'
Ok, per your comment
but i want to call menu method before loadData finishes
the issue lies here :
_menu = [[DOPNavbarMenu alloc] initWithItems:#[strArray] width:self.view.dop_width maximumNumberInRow:_numberOfItemsInRow];
Before loadData is run, I assume that strArray is nil. This causes this part #[strArray] to fail - this creates a new array with strArray as its only element, which cannot be nil.
I also assume that you wanted to rather pass strArray itself there, not wrap it in another array.
Now, if you call menu before populating strArray in loadData, there will likely be no items present in the menu, unless you have a way to update it with new items after loadData finishes.
To summarise : to fix your immediate issue, you should change the above line to this :
_menu = [[DOPNavbarMenu alloc] initWithItems:strArray width:self.view.dop_width maximumNumberInRow:_numberOfItemsInRow];
which should work, but there won't be any items present in the menu, because of reasons explained above.
hi i am new to iphone programing,i am using EGOPhotViewer and want to show images by using this code,
for ( recipeImages in recipeImages.imgArray) {
photo = [[MyPhoto alloc] initWithImageURL:[NSURL URLWithString:recipeImages.recipie_img_url]name:recipeImages.recipe_name];
NSLog(#"%#",recipeImages.recipie_img_url);
MyPhotoSource *source = [[MyPhotoSource alloc] initWithPhotos:[NSArray arrayWithObjects:photo ,nil]];
photoController = [[EGOPhotoViewController alloc] initWithPhotoSource:source];
}
[APPDELEGATE.navigationController pushViewController:photoController animated:YES];
and i get this error
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 2147483648 beyond bounds [0 .. 0]'
*** First throw call stack:
(0x225f012 0x2084e7e 0x2214b44 0x9e1e4 0xa46c4 0x1b45dc9 0x22b90c5 0x2213efa 0x1a7a482 0x1a8d73b 0xa9d7c 0xa6a4e 0xa5081 0xa0499 0x10af753 0x10afa7b 0x10bd590 0x10c55bd 0x10c5eab 0x10c64a3 0x10c6098 0x5bad6 0x2098705 0xfcf920 0xfcf8b8 0x1090671 0x1090bcf 0x108fd38 0xfff33f 0xfff552 0xfdd3aa 0xfcecf8 0x2c15df9 0x2c15ad0 0x21d4bf5 0x21d4962 0x2205bb6 0x2204f44 0x2204e1b 0x2c147e3 0x2c14668 0xfcc65c 0x263a 0x2545)
libc++abi.dylib: terminate called throwing an exception
i solved this by writing this code
NSMutableArray *localImagesArray = [[NSMutableArray alloc] init];
for ( recipeImages in recipeImages.imgArray) {
photo = [[MyPhoto alloc] initWithImageURL:[NSURL URLWithString:recipeImages.recipie_img_url]name:recipeImages.recipe_name];
NSLog(#"%#",recipeImages.recipie_img_url);
NSLog(#"%#", [photo debugDescription]);
[localImagesArray addObject:photo];
}
MyPhotoSource *source = [[MyPhotoSource alloc] initWithPhotos:localImagesArray];
photoController = [[EGOPhotoViewController alloc] initWithPhotoSource:source];
[APPDELEGATE.navigationController pushViewController:photoController animated:YES];
}
[__NSArrayI objectAtIndex:]: index 2147483648 beyond bounds [0 .. 0]'
2147483648 is NSNotFound. Somewhere in your code, or the code of a library you are using, something like indexOfObject: is being used on one array, and that index is being used to get a value from another array, and it is failing.
Your for loop looks very suspect. You're assigning a value to photoController at the end of each iteration, meaning only the value you assign last will actually get used. I'm not familiar with the library you're using but you probably want to be building up an array of MyPhoto objects before passing them to a single photoController.
Make sure initWithImageURL: name: inside MyPhoto returns self.
Verify this with NSLog(#"%#", [photo debugDescription]);
I have a piece of code where I'm trying to add items to an AVQueuePlayer iteratively, as follows:
for (int i = tempNowPlayingIndex - 1; i < [_itemsForPlayer count]; i++) {
[self insertItem:[_itemsForPlayer objectAtIndex:i] afterItem:nil];
}
_itemsForPlayer is a NSMutableArray containing AVPlayerItems.
Whenever I reach this line on execution, however I get a
'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
error. I know that the line responsible is
[self insertItem:[_itemsForPlayer objectAtIndex:i] afterItem:nil];
because commenting that line out removes the error. I had assumed that the problem was that [_itemsForPlayer objectAtIndex:i] wasn't returning an AVPlayerItem, but adding a print statement to print [_itemsForPlayer objectAtIndex:i] gives me:
<AVPlayerItem: 0x2002be60, asset = <AVURLAsset: 0x2003c0e0, URL = ipod-library://item/item.mp3?id=8966039988459606203>>
So the code should be able to add it to the AVQueuePlayer just fine. Does anyone have any ideas?
EDIT: Many thanks to #borrrden, who answered the question in a comment - I've overridden insertItem:afterItem elsewhere in the class, and the error was coming from an issue in the overridden method. Talk about your stupid mistakes - thanks again, Borrrden!