I have a AQGridView , The "initialization" of the grid works great,
but when i do [gridView reloadData], it will crash with the error
2012-01-03 21:27:40.338 XXX[8454:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary setObject:forKey:]: attempt to insert nil key'
After a couple of tries i've tracked the error coming from AQGridView's enqueueReusableCells. Its trying to get cell.reuseIdentifier and its value is nil for some weird reason.
Here's the code for gridView:cellForItemAtindex:
- (AQGridViewCell *)gridView:(AQGridView *)aGridView cellForItemAtIndex:(NSUInteger)index{
static NSString *CellIdentifier = #"SocialCell";
SocialCell *cell = (SocialCell *) [gridView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
cell = [[SocialCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier];
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"SocialCell" owner:nil options:nil];
for(id currentObject in topLevelObjects){
if([currentObject isKindOfClass:[SocialCell class]]){
cell = (SocialCell *)currentObject;
break;
}
}
}
As I said, first run works great, but the second run (reloading the data) , doesnt work as expected. This view includes 7 cells total so it doesn't even actually get dequeued, so i'm not sure why the value would be nil and crash.
Would appreciate any info on this :)
Thanks!
Related
I have created the table view using custom nib file in which i have add two images to create view like grid. When i add around 50 rows the app show me the message "memory warning" and then it will crash and Xcode show me the error "Message from debugger: Terminated due to Memory Pressure". I am testing app in iPhone 4s. it also crashes in iPhone 6. I am also using SDWebimage library for loading images. but even after comment the code of set images in "cellForRowAtIndexPath" method it crashes. Here is my code
SingleEventTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"SingleEventTableViewCell"];
if (cell == nil)
{
NSLog(#"cell allocated");
cell = [[SingleEventTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"SingleEventTableViewCell"];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SingleEventTableViewCell"
owner:self options:nil];
cell = [nib objectAtIndex:0];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
}
Can anyone suggest me how can I check memory leakage or something to resolve this issue.
I'm trying to delete multiple selections from a table view. Everything works fine until I scroll up or down, then it crashes and throws an exception.
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
Object can not be nil
This is how I am deleting the objects :
- (IBAction)deleteObjects:(id)sender {
NSArray *selectedRows = [self.tableView indexPathsForSelectedRows];
BOOL deleteSpecificRows = selectedRows.count > 0;
if (deleteSpecificRows)
{
NSMutableArray *stringsOfObjects = [NSMutableArray new];
for (NSIndexPath *selectionIndex in selectedRows) {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:selectionIndex];
[stringsOfObjects addObject:cell.textLabel.text];
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
NSString *plistPath = [path stringByAppendingPathComponent:#"AlertSubscriptions.plist"];
NSMutableArray *array = [[[NSMutableArray alloc] initWithContentsOfFile:plistPath] mutableCopy];
[array removeObjectsInArray:stringsOfObjects];
[self.alertSubArray removeObjectsInArray:stringsOfObjects];
[array writeToFile:plistPath atomically:YES];
[self.tableView deleteRowsAtIndexPaths:selectedRows withRowAnimation:UITableViewRowAnimationAutomatic];
}
Again this all works fine, unless I scroll up/down to select/deselect more cells so I subclassed my cells because I read that won't reuse cells on SO.
For reference:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
SubscriptionsTableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
cell = [[SubscriptionsTableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:nil];
}
cell.textLabel.text = [self.alertSubArray objectAtIndex:indexPath.row];
cell.textLabel.textAlignment = NSTextAlignmentLeft;
return cell;
}
Ive tried it with a static cell and without. I've tried setting dequeueReusableCellWithIdentifier to a static cell and without. Neither work when I scroll
static NSString *CellIdentifier = #"Cell";
Error log:
2015-06-28 15:46:19.379 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:
(0x186d3c2d8 0x1985680e4 0x186c234c0 0x10017e7d8 0x18b7b1404 0x18b79a4e0 0x18b7b0da0 0x18b7b0a2c 0x18b7a9f68 0x18b77d18c 0x18ba1e324 0x18b77b6a0 0x186cf4240 0x186cf34e4 0x186cf1594 0x186c1d2d4 0x1904336fc 0x18b7e2fac 0x1001646d4 0x198be6a08)
libc++abi.dylib: terminating with uncaught exception of type NSException
EDIT
So after trying what the others have told me to do I have done the following:
Set an exception breakpoint. The line that populates after crash is the [stringsOfObjects addObject:cell.textLabel.text]; line.
i have made sure my cellForRowAtIndexPath method was set up properly now:
}
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.backgroundColor = [UIColor whiteColor];
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
[self.tableView setRowHeight:45];
cell.textLabel.text = [self.alertSubArray objectAtIndex:indexPath.row];
cell.textLabel.textAlignment = NSTextAlignmentLeft;
return cell;
}
After that I still get a crash at adding the objects to the NSMutableArray so I looked in the debugger and made sure my UITableViewCell isn't nil like Robot mentioned to me, and it looks like it is but I don't know where to go from here: because in my mind it is not nil
As you can see, I have selected 6 rows but it only added 2 objects. I don't know why this is so difficult, why is it nil when some aren't? And why can I delete them perfectly fine without scrolling to select more?
So, after an extensive discussion in the comments the problem seems to be the following:
The logic of [stringsOfObjects addObject:cell.textLabel.text]; in the deleteObjects: method is wrong. This is because it is taking the text direct from the cells rather than the array backing store that populates the cells.
Cells can be scrolled offscreen and re-used so the text in them is no longer correct and, in fact, the cell no longer "exists" as it has been reused. If the cell doesn't "exist" an empty cell will be created where the text field might be nil. Note that cell re-use is a good thing; don't create cells and never re-use them or you will run out of memory fast.
Instead, take the text from your backing store that populates the cells themselves rather than from the cell directly. I would expect code something like:
[stringsOfObjects addObject:[self.alertSubArray objectAtIndex:selectionIndex.row]];
Here is part of my code :
LocalPosts *cell = (LocalPosts *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"LocalPosts" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
I have a .xib named LocalPosts - my code fails just there with Thread 1 - Breakpoint 1.1
I have all exceptions ON and enabled Zombies but I do not see anything printed on the console - just the (lldb).
I am running it on ios 8.0 on a device and I am using latest xcode.
I don't even know where to look at - can you help me on that?
Thanks
I'm having a hard time understanding the following block of code inside cellForRowAtIndexPath:
NSString *uniqueIdentifier = #"SliderCellWithComments";
SliderCellWithComment *cell = nil;
cell = (SliderCellWithComment*) [tableView dequeueReusableCellWithIdentifier:uniqueIdentifier];
if(!cell)
{
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"SliderCellWithComment" owner:nil options:nil];
for (id currentObject in topLevelObjects)
{
if([currentObject isKindOfClass:[SliderCellWithComment class]])
{
cell = (SliderCellWithComment*)currentObject;
cell.delegationListener = self; //important!!
cell.indexPath = [indexPath copy]; //important!!
break;
}
}
[cell setNameLabelText:#"Days to display:"];
.
.
.
I got this code from StackOverflow and it worked fine until I tried running it on iOS 5.1, where it crashes with an error: 'NSInternalInconsistencyException', reason: 'The NIB data is invalid.'
But what I do not understand about the code is that it doesn't seem to really re-use anything.
For instance:
Why does this code assign a value to "cell" twice?
cell=(SliderCellWithComment*)[tableView dequeueReusableCellWithIdentifier:uniqueIdentifier];
cell = (SliderCellWithComment*)currentObject;
If 2 executes, according to me, nothing is being re-used since the cell is assigned a value from new nib.
I don't really get the use of the Array either, why does the following code render blank cells:
static NSString *CellIdentifier = #"SliderCellWithComments";
SliderCellWithComment *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[SliderCellWithComment alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
[cell setNameLabelText:#"Days to display:"];
cell.delegationListener = self; //important!!
cell.indexPath = [indexPath copy]; //important!!
.
.
.
Actually the code is reusing cells. [tableView dequeueReusableCellWithIdentifier:uniqueIdentifier]; is asking the table view if he can find a cell with that identifier that can be reuse, if there is a cell that can be reused then the cell will not be nil and the code from the if(!cell){} will not be executed, if the table doesn't find a cell then the if(!cell){} block will be executed and a new custom cell will be created from a xib file.
I don't really get the use of the Array
What you are having there (that array) is a default way of loading a custom view from a xib file.
why does the following code render blank cells
Because in that piece of code you are calling a method from UITableViewCell that is probably not implemented in your custom cell because the custom cell initialization will be done using the xib file (that array that is mentioned in the first quote:)
new to ios programming. When i run the simulator I get this error.
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle (loaded)' with name 'cusCell''
here is the line that i get the error
static NSString *CellIdentifier = #"cusCell";
customCell *cell = (customCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
==> NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"cusCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
Sometimes this error can occur when you rename some files directly, and XCode fails to comprehend it. Just remove the file's reference from your project (Right Click - Delete and "Remove Reference")and just drag and drop again the files into your project. It worked for me.