In my application I try to load contents from a url, store them in a mutable array and show them in a table view. But I can't get it working, because every time I run the app this error appears:
*** Terminating app due to uncaught exception 'NSRangeException',
reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
*** First throw call stack:
(0x34dd088f 0x36d9e259 0x34d2823d 0x316e562f 0x315f09a9 0x313c0c5d 0x313c1b95 0x313c1ae7
0x313c16c3 0xa5cfb 0x33623ec7 0x35387a09 0x35390051 0x33622965 0xa4dc1 0x313a8e33
0x313cd629 0x31391d7d 0x314544dd 0x3139a55d 0x3139a579 0x3139a40b 0x3139a3e7 0x313a8015
0x313a1985 0x3136fc6b 0x3136f70f 0x3136f0e3 0x3439222b 0x34da4523 0x34da44c5 0x34da3313
0x34d264a5 0x34d2636d 0x313a0a13 0x3139de7d 0xa4745 0xa46dc)
terminate called throwing an exception
I create the array that should populate the table in my viewDidLoad with:
_videos = [[NSMutableArray alloc] init];
Then I connect to the url and parse through the received xml data. This works just like it should. When a certain tag is opened I create my video objects and after filling them with data I add those objects to my array with:
[_videos addObject:currentVideo];
This seems to work as well, because it returns the correct number of videos when
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _videos.count;
}
is called. But after this point the app crashes and I don't even reach the point where I try to populate my table view. The function looks like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
Video *curVideo = [_videos objectAtIndex:indexPath.row];
static NSString *CellIdentifier = #"CustomCell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.titleLabel.text = [curVideo title];
cell.descLabel.text = [curVideo desc];
return cell;
}
What am doing wrong?
Thanks in advance
I had the same error signature -[__NSArrayI objectAtIndex:]: index 4 beyond bounds [0 .. 1]' when attempting to present a modal Storyboard, table view with two (updated from five) static table cell sections. This error didn't come up until I removed three table cell sections I no longer needed in the view. After checking all my objectAtIndex references preceding the modal presentation at length for two days, I decided to look at the UITableViewController subclass code itself. I found this:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
//#warning Potentially incomplete method implementation.
// Return the number of sections.
return 5;
}
Then the lightbulb went off. The index 4 being referred to related to my table view number of sections and the bound of [0 .. 1] referred to my current two table cell sections. Updating the return value to match the number of current table cell sections in the Storyboard table view resolved the issue.
Somewhere you are likely accessing _videos prior to initializing it. Most likely you'd doing it after init, but prior to loading the view. The fix for this kind of problem is to use accessors exclusively, and to lazy-initialize self.videos. This is one of many reasons never to access your ivars directly except in init and dealloc.
#interface ...
#property (nonatomic, readonly, strong) NSMutableArray *videos;
#end
#implementation ...
{
NSMutableArray *_videos; // Can't auto-synthesize. We override the only accessor.
}
- (NSMutableArray *)videos {
if (! _videos) {
_videos = [NSMutableArray new];
}
return _videos;
}
Now all references to self.videos will be initialized no matter when they happen.
You can also initialize videos correctly in init, which takes a little less code:
#interface ...
#property (nonatomic, readonly, strong) NSMutableArray *videos;
#end
#implementation ...
- (id)init {
self = [super init];
if (self) {
_videos = [NSMutableArray new];
}
return self;
}
I have passed dummy image name for images array like this,
arrImages = [NSArray arrayWithObjects:[UIImage imageNamed:#"some.png"]
The above line caused me error. So I changed #"some.png" with existed image like #"category.png".
This is worked for me. Make sure you are passing correct image name from your bundle.
Related
I have my main view controller that shows a UITableView.
Each cell of this are custom (I've created a UIView for custom presentation).
For showing these items in my tableView, I populate an array with the content of the "allFilesFolderPath" folder with this code:
- (void)configureView {
_itemArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:allFilesFolderPath error:nil];
}
and
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.itemArray count];
}
and I create my custom cells for showing them with :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger row = [indexPath row];
myItem = [self.itemArray objectAtIndex:row];
NSLog(#"My Item : %#", _itemArray.description);
static NSString *CellIdentifer = #"cardCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifer];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifer];
}
return cell;
}
When I print the array with the NSLog, I get the correct list of item and in the alphabetical order (like how they are stored in the Documents location on my iPhone):
My Item : (
Music,
Music10,
Music2,
Music3,
Music4,
Music5,
Music6,
Music7,
Music8,
Music9,
Photos,
Videos
)
But when I run the app in my iPhone (or in the simulator), the cells are correctly displayed (in the order) until the eighth item. After this number, in my case, instead of having "Music8", "Music9", "Photos", "Video" I come back to the beginning of th array so "Music", "Music10", "Music2" and "Music3"
To better understand what I get, here is the screenshots :
I'm really lost! I've searched (and search again) what I'm doing wrong but I don't find anything, everything is correct for me.
Please help me to find my issue so that I can sleep normally.
EDIT: here is the method I've set to retrieve the myItem string from my other class :
+ (NSString *)getItemName {
return myItem;
}
And here is how I retrieve it from my other class :
NSString *test = [ViewController getItemName];
_itemName.text = test;
EDIT2 : Here is the code used for setting my custom TableViewCell
(sorry for missing these informations
#import "TableViewCell.h"
#implementation TableViewCell
- (void)awakeFromNib {
// Initialization code
[self cardSetup];
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)cardSetup {
_cardView.layer.masksToBounds = NO;
_cardView.layer.shadowOffset = CGSizeMake(0, 1);
_cardView.layer.shadowRadius = 1;
_cardView.layer.shadowOpacity = 0.3;
NSString *test = [ViewController getItemName];
_itemName.text = test;
}
#end
There is this call named "dequeueReusableCell...". Table view cells are reused. If 8 cells fit on the screen, and you scroll the view up, your ninth row will reuse the cell that was used for the first row. That's why you have to set up your cell in cellForRowAtIndexPath, which apparently you refuse to do.
Cells are used just for display. They are not used for storing data. You should have a data model, accessed by everyone. cellForRowAtIndexPath reads from that data model. And then if something happens (for example by tapping on a button in a cell) that changes the data model, then you change the data model, and the data model should tell all the interested parties that the model has changed.
Your cell in one view and a UILabel elsewhere should definitely not be connected at all. Any changes should propagate through your data model.
You're not using myItem anywhere in cellForRowAtIndexPath: Your cells seem to be getting their text from some other method, when they should be getting it from celForRowAtIndexPath:
So I am building a simple, two-view application in which a user generates a score, and then navigates to the LeaderboardViewController where their latest score is added to an array, and shown in a table view.
I have everything pretty much working
1. Passing score from initial view controller to the LeaderboardViewController
2. Log the _scoreToBeAdded int variable to the console to make sure I have it in the new view controller
2. Created a dummy array and populate a table view with the array data.
Problems
The only problem is, I can't seem to add a new object (_scoreToBeAdded) to the scores NSMutableArray without causing a crash.
In addition, I'm also unsure the best way to initialise the array without needing to add the "TODO, dummy data" objects in the array.
Any guidance is much appreciated! :)
Crash message:
2015-04-06 12:22:20.627 Bugland[15976:607] *** Assertion failure in -[UITableView _configureCellForDisplay:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2935.137/UITableView.m:6509
2015-04-06 12:22:20.635 Bugland[15976:607] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
*** First throw call stack:
Edit: If I edit out the following line,
[scores addObject:anumber];
I get no problem, and no app crash.
LeaderboardViewController.m
#import "LeaderboardViewController.h"
#interface LeaderboardViewController ()
#end
#implementation LeaderboardViewController
{
NSMutableArray *scores; //Init array
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Initialize some dummy array and table data
scores = [NSMutableArray arrayWithObjects:#"TODO: Enter real data here", #"TODO: Enter real data here", nil];
//Turn the _scoreToBeAdded into an NSNumber
NSNumber *anumber = [NSNumber numberWithInteger:_scoreToBeAdded];
//Attempt to add the number to the array - this line is a problem
[scores addObject:anumber]; //This line is causing issues.
NSLog(#"Leaderboard loaded w new score to add %i", _scoreToBeAdded);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [scores count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [scores objectAtIndex:indexPath.row]; //I assume this line is also causing an issue based on the error log.
return cell;
}
I'm facing a problem that I not truly understand the reason. The exception does not give me a clue to understand the problem.
I want to modify content of UILabel at my interface according to the data given in myArray. However, as the line I specified at function "cellForRowAtIndexPath" the program fires an exception.
What is the reason for this problem?
#property (strong, nonatomic) NSMutableArray *myArray; //
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[myArray addObject:#{#"field1": #"myfield1"}]
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section {
return self.myArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
// Configure the cell...
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
UILabel *myLabel = (UILabel *)[cell viewWithTag:100]; // myLabel is successfully created with the given viewWithTag
NSLog(#"Object at indexpath.row: %ld", (long)indexPath.row); // Object at indexpath.row: 0
NSLog(#"The obj of the array = %#",[self.myArray objectAtIndex:indexPath.row] ); // The obj of the array = {field1: #"myfield1"}
myLabel.text = [[self.myArray objectAtIndex:indexPath.row] objectForKey:#"field1"]; // this part fires the exception given below.
return cell;
}
//getter for myArray
-(NSMutableArray *)myArray{
if(! _myArray){
_myArray = [[NSMutableArray alloc] init];
}
return _myArray;
}
The error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFArray objectForKey:]: unrecognized selector sent to instance 0x1459d1f0'
Rather than tell you what to change your code, I'll give you some pointers so you will hopefully be able to resolve your problems in the future a bit easier.
First, the error message you have is this
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFArray objectForKey:]: unrecognized selector sent to instance 0x1459d1f0'
The exception message is the key point here
unrecognized selector sent to instance
If you search for this message using the search engine of your choice, you'll see that this means you are calling a method on an object that doesn't respond to that method. The error message also tells you the method you are trying to call, and on which type of object you are calling it.
[__NSCFArray objectForKey:]
If you look at the documentation for the NSArray object, you'll see that there is no objectForKey method available for that.
What you should now do is set a breakpoint in your code (if you don't know about breakpoints, go off and read about them - they are IMPORTANT for debugging) and step through until you hit the line that is throwing the exception. At this point, you can inspect the objects you have and see what the types are. You should then be able to work out what you should do with the coding.
[__NSCFArray objectForKey:]: unrecognized selector sent to instance 0x1459d1f0'
You can't call objectForKey for NSMutableArray
Maybe you should use NSDictionary if you need to use objectForKey:
or you can use array of arrays
ex:
NSArray *array = [[NSArray alloc] initWithObjects:#"field1Value",#"field2Value",#"field3Value",nil];
[self.myArray addObject:array];
Now , when you need to retrieve some fields value, then just call the index in the array
NSArray *array = [self.myArray objectAtIndex:[indexPath row]];
NSString* valueField1 =[array objectAtIndex:0];
Hope this will help:)
Edit:
If you need to use NSDictionary
self.myArray=[[NSMutableArray alloc]init];
dict=[[NSDictionary alloc] initWithObjectsAndKeys:#"value",#"KeyName",nil];
[self.myArray addObject:dict];
myLabel.text = [[self.myArray objectAtIndex:indexPath.row] objectForKey:#"KeyName"];
The exception does not give me a clue to understand the problem.
I disagree, the exception tells you exactly what you did wrong. It tells you that you sent objectForKey: to an array instead of to a dictionary. The only line where I see you using objectForKey: is this one.
myLabel.text = [[self.myArray objectAtIndex:indexPath.row] objectForKey:#"field1"];
which means that [self.myArray objectAtIndex:indexPath.row] is an array, not a dictionary. I don't know how that happened because nowhere in your code that you show us is there anything that adds an object to self.myArray. In particular, this doesn't:
[myArray addObject:#{#"field1": #"myfield1"}]
It should say
[self.myArray addObject:#{#"field1": #"myfield1"}];
I suspect that was just a copy error though because you also forgot the semicolon. Note that just putting an underscore on the front of myArrayisn't any good because you rely on the accessor to initialise the array.
If you store NSDictionary or NSMutableDictionary to array then then the code will work for you. If you want to add NSDictionary to array you should use: [[NSDictionary alloc] initWithObjectsAndKeys:#"value1", #"key1", #"value2", #"key2", nil]
To anyone facing a similar exception, check all your IBActions and IBOutlets!
I deleted a function but forgot to right click on the button on the Main.story board to delete the outlet/action there.
example below:
Here we have 2 outlets, called "test" and "test2" respectfully, for the button in the upper left corner
Here I deleted the code for "test2" outlet, but when I rightclick in the button the reference is still there.
I've read all similar questions and tried all suggestions, still nothing. Maybe someone can spot my flaw.
My view controller is initiated from another view controller, by one of two buttons. Button taps send NSNotification (with attached arrays), and this view controller anticipates this notification and then calls this method:
- (void)addContentToArray:(NSNotification *)aNotification {
array = [NSArray arrayWithArray:[aNotification object]];
([array count] == 6) ? (category = YES) : (category = NO);
[myTableView reloadData];
NSLog(#"%d", [array count]);
NSLog(#"%#", myTableView);
}
The method gets called every time, I can see that from changing array count. Here notification object is the array passed from previous view controller, and I assign these objects to my local array property - this is my UITableView source. So what I do is I try to reuse the UITableView to display elements of whatever array is being passed. And it works nicely for the first array passed (whichever first).
When I tap the second button, the new array is passed successfully (as mentioned before, I know that from log of [array count] which is different: 3 vs 6 objects in different arrays). However, what is not happening is that UITableView does not refresh (although the values passed when I select a row in the table are from the correct arrays, even though wrong values are displayed).
Here are UITableView data source methods:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [array count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Identifier"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"Identifier"];
}
cell.textLabel.text = [[array objectAtIndex:indexPath.row] objectForKey:#"name"];
if (category) {
cell.detailTextLabel.text = [[array objectAtIndex:indexPath.row] objectForKey:#"description"];
}
return cell;
}
So, what am I doing wrong?
A few other considerations that might help:
NSLog(#"%#", myTableView); returns (null), which is a bit worrying. myTableView here is UITableView from my nib file, which is correctly connected to the view controller, declared as property and synthesized
The view controller in question is a rightViewController of the PKRevealController, so when it is called repeatedly, viewWillAppear method is called, but not viewDidLoad (although, as I already mentioned, addContentToArray: method is being called every time as well)
Also, for those somewhat familiar with PKRevealController - when I try and log focusedController from my view controller, it says that frontViewController - the one that moves to reveal my view controller - is the one that is focused. Can that be the reason why myTableView is (null)?
I'd be grateful for any insight and help!
Need more code, that part where you created and call Myviewcontroller's addContentToArray method.
I think you used release code there for Myviewcontroller's object, try once with hide that part.
I managed to solve the issue by editing initWithNibName method (old line commented out)
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
//self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
self = [super initWithNibName:#"PurposeCategoryViewController" bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
Apparently, it did have something to do with the fact that my view controller (called PurposeCategoryViewController) was not the top/focused view controller in PKRevealController hierarchy. So, I just needed to specifically indicate my nib file.
What value are you returning in this delegate method:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
make sure it is 1
i have looked through basically every single stack overflow question on this, but i cant find an answer. None of the answers seem to work.
I am writing an application that has a tableview in it, with a uitableview as a subview.
The uitableview is datasource and delegate connected to a class called xvalues, which is a subclass of uitableviewcontroller. i also have a class, where i load a custom uitableviewcell. This all doesn't cause any errors.
Here is my code for the uitableview, in xvalues:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
tableviewcell *cell = [[tableviewcell alloc]initWithFrame:CGRectZero];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/
}
I removed some commented out methods such as can edit row at index path and commit editing style.
In cellforrowatindexpath, tableviewcell is my custom cell class.
From this, when i run my code, it loads up my uitableview, with 1 cell, with my custom cell.
However, now, if i click and drag, it works for dragging about an inch, and then suddenly crashes with the error:
2012-07-16 12:14:16.957 spreadsheet[68717:f803] -[__NSCFString tableView:cellForRowAtIndexPath:]: unrecognized selector sent to instance 0x6894400
2012-07-16 12:14:16.960 spreadsheet[68717:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString tableView:cellForRowAtIndexPath:]: unrecognized selector sent to instance 0x6894400'
*** First throw call stack: blah blah blah
It also happens when i click on the row, but i think that is because of my did select row at index path method.
If anyone could help me it would be amazingly helpful.
Your table view controller is getting deallocated. Make sure you’re retaining your xvalues instance (or assigning it to a strong property on something, like your app delegate) wherever you’re creating it.