-(IBAction)someMethod:(UIStepper *)sender{
int x=sender.value; //This is an integer from 0-8;
NSLog(#"%f",sender.value);
NSArray *rpmValues = [[NSArray alloc]initWithObjects:#"a",#"b",#"c",#"d",#"e",#"f",#"g",#"h",#"i", nil];
if (x<=[rpmValues count]) {
myLabel.text = [rpmValues objectAtIndex:x];
}
NSLog(#"%i",[rpmValues count]);
}
Above is my code, what I want to do is to change UILabel display by changing UIStepper. This is very straight forward. But when I change press the stepper value, it crashes:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** - [__NSArrayM objectAtIndex:]: index 1 beyond bounds for empty array'
*** First throw call stack:
And the [rpmValue count] is 9. I really got confused. Can anyone help me?
That code seems fine (see my comment on the question); your problem could arise from the use of
if (x<=[rpmValues count]) {
This will include the count of the array, which exceeds the index range by one. Use
if (x < [rpmValues count]) {
At the very least if (x<=[rpmValues count]) should be if (x<[rpmValues count]). Otherwise if you have an array with, say, two entities then you're allowing yourself to access indices 0, 1 and 2 — three possibilities in total.
Is it possible you've set a maximumValue on your stepper of '9' based on similar logic?
Related
I have a textView that displays the string: 255,34,7,4
I'm trying to use the following code to pull the string from my textView, and separate each number into an array:
NSArray *array = [self.textview.text componentsSeparatedByString:#","];
NSString *comp1 = array[0];
NSString *comp2 = array[1];
NSString *comp3 = array[2];
This works, and the following is returned to my array:
> 2020-07-11 15:21:58.110560-0700[10116:2311809] In the array you will
> find (
> 255,
> 34,
> 7,
> 4 )
However I'm unable to access the second and third values with array[1] and array[2]? My app crashes with the following error:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSSingleObjectArrayI objectAtIndex:]: index 1 beyond
bounds [0 .. 0]'
Why is this happening?
because the moment you try to access the expected objects do not exist.
It is much safer to ask for the amount of indexes available in an array before accessing indexes that may not exist at runtime.
NSArray *splitarray = [self.textview.text componentsSeparatedByString:#","];
NSLog(#"amount of indexes %lu", splitarray.count);
for (NSString *idxObject in splitarray) {
NSLog(#"content #%",idxObject);
}
or
for (NSUInteger i=0; i<splitarray.count; i++) {
NSLog(#"content #%",splitarray[i]);
}
NSArray and a lot of other indexed data types do not check if an index exists to speed up accessing and they are also not constructed to return nil in case the index does not exist.
I have this simple piece of code when I am logging variable's value:
NSLog(#"set.nflag - %#", set.nflag1);
if (set.nflag1 == [NSNumber numberWithInt:1])
{
NSLog(#"set.nflag - %#", set.nflag1);
[sectionArray insertObject:_checkboxCell atIndex:set.nflag1];
}
at last row I have crash an log is:
2013-09-26 11:36:12.537 PharmaTouch[1325:c07] set.nflag - 1 2013-09-26 11:36:12.537 PharmaTouch[1325:c07] set.nflag - 1 2013-09-26 11:36:12.538 PharmaTouch[1325:c07] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM insertObject:atIndex:]: index 127347632 beyond bounds for empty array'
What can cause of changing value for
set.nflag1
?
The exception shows that sectionArray isn't allocated. Add this somewhere before this gets executed.
sectionArray = [NSMutableArray alloc] init];
Try adding:
NSInteger index = [set.nflag1 intValue];
[sectionArray insertObject:_checkboxCell atIndex:index];
In your code, the
set.nflag1
is of type NSNumber*. This is a pointer, not NSUInteger.
Do this:
[sectionArray insertObject:_checkboxCell atIndex:set.nflag1.unsignedIntegerValue];
Also, when comparing NSNumbers, use isEqualToNumber: method or just retrieve the int before the comparison.
Make sure you allocate the NSMutableArray before you try the insertion. Also, look out not to give it too big index
Raises an NSRangeException if index is greater than the number of elements in the array.
1 is beyond the bounds of an empty 0 indexed array.
Try adding a guard to check the array length before insertion.
Or try simply adding it to the end of the array or
Pad your array with instances of the NSNull singleton if you really need the NSNumber at the eponymous index.
I have a table view in which I'm using sectionIndexTitlesForTableView to display an index. I have to display a list of universities located in different countries. Each Country can have more than one university so the table displays like this:
1. Ecuador
1. Universidad Catolica del Ecuador
2. El Salvador
1. Universidad Don Bosco
3. Estonia
4. Tallin University
4. Tartu Health Care College
4. University of Tartu
4. Finland
5. Aalto University
....
What I intend to do is, using the scroll search at the side, when the user touches "A" it will take you to the first entry with the letter A. For example, when I press "E" it should take me to the section "Ecuador" (displayed on the "image" above).
The problem came at the start because I had multiple sections, when I pressed "B" it would take me to "Australia", the second section (the first being Argentina) instead of taking me to "Belgium" which would be the first Country with the B letter. I managed a workaround of this but it's giving me errors. Here's the code:
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles];
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
NSArray* bu =[self SectionsASaltar];
int ins =[[bu objectAtIndex:index] intValue];
return [[UILocalizedIndexedCollation currentCollation] sectionForSectionIndexTitleAtIndex:ins];
}
-(NSArray*)SectionsASaltar
{
NSArray* ALF= [[NSArray alloc] initWithObjects:#"A",#"B",#"C",#"D",#"E",#"F",#"G",#"H",#"I",#"J",#"K",#"L",#"M",#"N",#"O",#"P",#"Q",#"R",#"S",#"T",#"U",#"V",#"W",#"X",#"Y",#"Z", nil];
NSMutableArray* jumps =[[NSMutableArray alloc]initWithObjects:#"0", nil];
int i=0; //contador de elementos
int j=0; //contador del alfabeto
[titl addObject:[self.secc objectAtIndex:i]];
do {
if ([[self.secc objectAtIndex:i] hasPrefix:[ALF objectAtIndex:j]]) {
i++;
}else{
[jumps addObject:[NSString stringWithFormat:#"%d",i]];
i++;
j++;
}
} while (i<[self.secc count]);
[jumps addObject:[NSString stringWithFormat:#"0"]];
NSLog(#"%#",jumps);
return jumps;
}
Where self.secc is my array with the sections and jumps is an array with the number of elements I have to skip on the index to get to next letter.
The idea of the code above is to count how many elements have the letter A, store that and skip them when the users press B, so it will go directly to the first letter B. It works fine for most of the letters but once I press around the letter M it gives me the following error:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray objectAtIndex:]: index (29) beyond bounds (28)'
*** First throw call stack:
(0x25f9012 0x21c6e7e 0x25f8deb 0x25ed7e0 0x13137be 0x1dcd2 0x10d27ee 0x21da705 0x102e920 0x102e8b8 0x10ef671 0x10efbcf 0x124396d 0x12439a6 0x10ee7e2 0x105e16d 0x105e552 0x103c3aa 0x102dcf8 0x32b3df9 0x32b3ad0 0x256ebf5 0x256e962 0x259fbb6 0x259ef44 0x259ee1b 0x32b27e3 0x32b2668 0x102b65c 0x2bbd 0x2af5 0x1)
libc++abi.dylib: terminate called throwing an exception
(lldb)
The thing I really don´t know where I’m going beyond bounds, I think it is in the line :
return [[UILocalizedIndexedCollation currentCollation]
sectionForSectionIndexTitleAtIndex:ins];
but I don´t know how that statement works so I don´t know how to fix it. Any ideas?
Also, is this the best approach for my indexing or is there an easier way to manage same-lettered sections. I know I can make another view, then have the first view have only countries ordered by letters and in a second view the universities, but I’m trying to avoid that.
Your code assumes there is an entry for every letter in the alphabet. If not, then it will increment both i and J, skipping the active entry. So if you have an array that starts with the letters a, c, d, e then your code will test a with a, then c with b, incrementing both indexers and in the next loop it will test the d with c instead of c with c. Because you keep incrementing j you can go past your index of items.
I am using a singleton class to transfer a NSMutableArray across views.
The issue I am having is my array is getting displayed multiple times.
Right now I am working with three UITextFields. Each is getting added to the array and outputted in a specific format. Here is what my output looks like:
A / B
C
A / B
C
A / B
C
All I need shown is:
A / B
C
Here is my code if someone can help me find what is missing or needs to be reworked:
To display the text:
UILabel * myLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 300, 200)];
[myLabel setFont:[UIFont fontWithName:#"Helvetica" size:10.0]];
myLabel.numberOfLines = 0;
NSMutableString * string = [NSMutableString string];
Education * myEducation = [Education sharedEducation];
for (Education * output in myEducation.educationOutputArray)
{
[string appendString:[NSString stringWithFormat:#"%# / %# \n%#\n", [myEducation.educationOutputArray objectAtIndex:0], [myEducation.educationOutputArray objectAtIndex:1], [myEducation.educationOutputArray objectAtIndex:2], nil]];
}
myLabel.text = string;
[self.view addSubview:myLabel];
Here is where I am saving the text:
-(void)saveButtonTapped:(id)sender
{
[_educationArray addObject:_aTextField.text];
[_educationArray addObject:_bTextField.text];
[_educationArray addObject:_cTextField.text];
Education * myEducation = [Education sharedEducation];
myEducation.educationOutputArray = _educationArray;
[self.navigationController popViewControllerAnimated:YES];
}
EDIT *
When a user is entering text into the text fields they can also add a new set of text using the same three text fields.
If I removed the for loop only the first is displayed. How can I get all of the text to display?
EDIT TWO *
I tried this:
[string appendString:[NSString stringWithFormat:#"%# / %# \n%#\n", [output major], [output university], [output timeAtSchool]]];
Results in this error:
2012-12-29 17:03:07.928 EasyTable[14501:c07] -[__NSCFString major]: unrecognized selector sent to instance 0x7176850
2012-12-29 17:03:07.941 EasyTable[14501:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString major]: unrecognized selector sent to instance 0x7176850'
*** First throw call stack:
(0x1c99012 0x10d6e7e 0x1d244bd 0x1c88bbc 0x1c8894e 0x6162 0xff817 0xff882 0xffb2a 0x116ef5 0x116fdb 0x117286 0x117381 0x117eab 0x1184a3 0x118098 0x2c10 0x10ea705 0x21920 0x218b8 0xe2671 0xe2bcf 0xe1d38 0x2e5213 0x1c61afe 0x1c61a3d 0x1c3f7c2 0x1c3ef44 0x1c3ee1b 0x1bf37e3 0x1bf3668 0x1e65c 0x240d 0x2335 0x1)
libc++abi.dylib: terminate called throwing an exception
You add three elements at a time to the array, and later you want to process them three at a time.
It would probably be better to create a container class that holds the three elements, and add instances of the container class to the array.
But if you really want to do it this way, you can't use a for/in loop. You have to use an index variable:
NSArray *array = myEducation.educationOutputArray;
for (NSUInteger i = 0, count = array.count; i < count; i += 3) {
[string appendFormat:#"%# / %#\n%#\n", array[i], array[i+1], array[i+2]];
}
you don't have duplicates in the array: the problem is in the for loop
for (Education * output in myEducation.educationOutputArray)
{
[string appendString:[NSString stringWithFormat:#"%# / %# \n%#\n", [myEducation.educationOutputArray objectAtIndex:0], [myEducation.educationOutputArray objectAtIndex:1], [myEducation.educationOutputArray objectAtIndex:2], nil]];
}
here you are looping through the array 3 times (because there are 3 objects in the array) and then printing each object each time. I think you should just do the appendString: line wihtout the for loop
Your for loop is really odd; You loop through each object in the array but then you hardcoded the indexes inside the for loop. I'm not sure what's going on there but it's certainly the source of the odd output. That pointer to an Education object is what you should access. Each time through the loop, use the value of output.
If you're also having uniqueness issues, consider using an NSSet instead of an NSMutableArray. If you care about order, use NSOrderedSet. Set collection types do not allow duplicated values.
Also one more point: If you know you're only going to ever access the values at index 0, 1, and 2, there's really no point to having an NSArray. Just store each value separately and access it directly. At the very least there's no reason for the for loop.
Edit:
You're crashing because you think your array has Education objects in it but it really has plain strings:
-[__NSCFString major]: unrecognized selector sent to instance 0x7176850
Notice that it's saying that you tried to call the method major on an __NSCFString (a private subclass of NSString that apple uses internally). This is a good indicator that your array doesn't contain what you think it does. Make sure you're loading your data into your array correctly by constructing Education objects with the three pieces of data.
You also suggested that you tried
[string appendString:[NSString stringWithFormat:#"%# / %# \n%#\n", output]];
Basically what stringWithFormat: does is take that format string and use it like a template and then it takes as many arguments as you need to fill up the placeholders in the template. %# is a placeholder for an object's description so stringWithFormat: is going to expect three parameters after the format string to fill each %#.
I'm using JSON to parse data into an NSArray 'courseArray'. I then filter this data using NSPredicate and store it into 'rows'. The problem is, i dont know how to determine if 'rows' is empty or not. For example : If a record exists, rows will contain the appropriate objects, but if the record doesnt exist then the application crashes (also when i use NSLog to see the contents of the array its blank, i believe its supposed to say its nil? if there are no objects). How can i fix this?
if (dict)
{
courseArray = [[dict objectForKey:#"lab"] retain];
NSPredicate* predicate = [NSPredicate predicateWithFormat:#"labNumber== %#",labSelected]; //filter
rows = [[courseArray filteredArrayUsingPredicate:predicate]retain];
}
[jsonreturn release];
self.formattedTextView.opaque = NO;
self.formattedTextView.backgroundColor = [UIColor clearColor];
NSLog(#"array %#",rows);
**NSDictionary *currentSelection = [rows objectAtIndex:0];** (app crashes at this line - [NSArray objectAtIndex:]: index 0 beyond bounds for empty array')
NSString *labNumber = [currentSelection objectForKey:#"labNumber"];
-objectAtIndex: will raise an exception if there is no object at the nominated index. If rows is empty there won't be an object at index 0, hence the exception. As you don't catch the exception, the result is that your app is terminated.
You probably want to compare [rows count] to 0 to check that there's something in it and to react appropriately if not.
Try if([courseArray count] > 0) also another method that can be of help here is
[courseArray containsObject:(id)]