UITableView titleForHeaderInSection prints headers to console twice then crashes - objective-c

In the method below titleForHeaderInSection, for some reason the NSLog prints out the headers twice and then the app crashes in objc_msgSend. I can't understand why this would cause the app to crash?
It would seem from research that crashes in objc_msgSend are caused by sending messages to already freed objects, but is that the case here?
My sectionNames array is populated in viewDidLoad.
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *title = nil;
title=[sectionNames objectAtIndex:section];
NSLog(title);
return title;
}
Thanks

How are you populating your sectionNames array? It's possible that the array, not the string, is getting released prematurely.
UPDATE:
Your problem is that +arrayWithArray: creates an autoreleased array, which gets released when the current run loop finishes. You need to either retain sectionNames or use -initWithArray:

Related

Application crashing on numberOfRowsSection

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [array count]; // <--- Crashes here
}
I'm not sure why it is crashing considering the array is a simple NSArray.
Your "array" must not be an NSArray. Can you provide some context for where array is defined? Are you using ARC?
A simple test would be to put the following line before that return statement:
NSLog(#"array = %#; array class = %#", array, array.class)
Paste the output from that and I can help you further! My guess currently is that array is being deallocated, and there's some other (or garbage) property in that memory. I wouldn't be surprised if you saw that array.class was an NSNumber...

UITableViewDataSource and Multithreading

I'm running into index beyond bounds exception in one of my UITableViews and I think it could be down to some multithreading issues. Here's what I believe is happening:
I have a UITableView and it's data source is a regular NSMutableArray.
This NSMutableArray which is backing my UITableView is updated every couple of seconds with the contents of an API response.
After each update, UITableView's reloadData is being invoked to ensure that the user sees new data from the API server.
Sometimes a index beyonds bounds exception gets thrown.
Here's my code:
-(NSMutableArray*) currentBetEvents
{
return currentMarketId == nil ? [[BFOpenBetsModel sharedInstance] betEvents] : filteredBetEvents;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSArray *betEvents = [self currentBetEvents];
return [betEvents count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray *betEvents = [self currentBetEvents];
id obj = [betEvents objectAtIndex:indexPath.section] // this is where it blows up
Basically, I get an exception while trying to access an object in the betEvents structure at index 0.
What I believe is happening is:
reloadData is called on the UITableView
numberOfSectionsInTableView: is invoked which returns a value > 0.
a rouge thread arrives and clears out the UITableView's data source.
cellForRowAtIndexPath: is invoked and it bombs.
Is there any way to ensure that this doesn't happen? Do I need to start using some primitive locks on the data source to ensure that it doesn't get updated while the table is being updated?
EDIT
Took another look at how the data structures returned by currentBetEvents can be altered and it looks like the filteredBets & betEvents can be cleared out as a result of the following code:
[[NSNotificationCenter defaultCenter] postNotificationName:kUserLoggedOutNotification object:nil];
This notification is posted whenever the user logs out. Whenever a user logs out of the app, I need to clear out the filteredBets and betEvents arrays. Is it possible that the following could happen:
reloadData is called on the UITableView
numberOfSectionsInTableView: is invoked which returns a value > 0.
User logs out which kicks off the notification & clears out the data structures.
cellForRowAtIndexPath: is invoked and it bombs.
Thanks,
Sean
Definitely sounds like a threading problem. You might try something like this:
// view controller
#synchronized([[BFOpenBetsModel sharedInstance] betEvents])
{
[self.tableView reloadData];
}
…
// data model
#synchronized(_betEvents) // or whatever the instance variable -betEvents returns is
{
[_betEvents addObject:whatever];
}

Do i need to release NSMutableDictionary in this case?

Do I need to release dictCellCollectionIndividual in this case?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
... ...
... ...
... ...
// Local declaration of dictCellCollectionIndividual
NSMutableDictionary *dictCellCollectionIndividual;
// Copy the specific dictionary from dictCellCollection to dictCellCollectionIndividual. dict CellCollection is declared elsewhere.
dictCellCollectionIndividual = [dictCellCollection objectForKey:[NSString stringWithFormat:#"%#", [arrayCellCollectionOrder objectAtIndex:indexPath.row]]];
... ...
... ...
... ...
// Do I need to release?
[dictCellCollectionIndividual release];
return cell;
}
Doesn't using objectForKey increase the retain count? Don't I have to release it?
Thanks in advance.
No, it simply returns a pointer to the object held within the dictionary; if you plan to keep the object around for any period of time, you need to take ownership of it, so that the object will remain valid if NSDictionary is deallocated in the meantime. In this case, you'll need to make sure to either release or autorelease the object when you're done with it. If you're planning to use it only as a temporary value (say, as an argument to an NSLog call), it's probably unnecessary to retain the object, and therefore unnecessary to release it.

big memory problem in objective c

i've a function like this:
#property(nonatomic,retain) NSMutableArray *array;
#synthesize array = _array;
(NSMutableArray *) name
{
self.array = [[NSMutableArray alloc]init];
[_array addObject:object];
[object release];
return [_array autorelase];
}
In the other function i've a property like the property above, named result, and i make:
self.result = [... name];
Then in dealloc i make
[_result release];
and it crashes in this point, how can i solve this?
I've tried many roads, but or it crashes, or i see memory leak in Instruments, where am i wronging?
Thanks.
While there's a lot wrong with this code, the likely cause of your crash is that you're releasing object within -name without taking ownership of it- unless you're creating object within the method through a call to -alloc, -new, or -copy, that method doesn't own it and isn't responsible for releasing it. This is causing that object to be invalid within the NSMutableArray, so when _result releases, it attempts to release an invalid piece of memory and crashes.
Also, properties aren't simply local variables for individual functions, they're member variables for instances of the class for which you're writing these classes. If your end goal is only to return an autoreleased array and set it to result you could do the following:
- (NSMutableArray *) name {
//call a convenience method- it comes back autoreleased
NSMutableArray* theArray = [NSMutableArray array];
[theArray addObject:object];
//don't release object unless you took ownership of it in this function
return theArray;
}
then outside the function, either call self.result = [... name] or [self setResult:[... name]];
You have a very strange method definition (the header should have a - before the return type), and inside that definition you are accessing a variable called object that doesn't seem to exist. I'm not sure what you want, but you've got at least one memory problem. The array that you create in name gets leaked every time the method is called. If you add some details, like the crash message, someone may be able to help more.

"componentsSeparatedByString" Memory leak

I am facing some strange memory leak in our existing iPad application,
Here is a function which gives memory leak in instrument
-(NSString *)retriveInfo:(NSString*)fromstring:(NSString*)searchstring
{
NSArray *arrRetrive = [fromstring componentsSeparatedByString:searchstring];
if([arrRetrive count]!=0){
if ([arrRetrive count]!=1){
NSString *strDisplayOrder = [arrRetrive objectAtIndex:1];
arrRetrive = [strDisplayOrder componentsSeparatedByString:#"<"]; //MEMORY LEAK
}
}
return [arrRetrive objectAtIndex:0];
}
Here is a input parameter
Param 1 : <displayorder>1</displayorder><filename>201103153_0100.pdf</filename><title>【1面】東日本巨大地震直撃、日経平均一時675円安[br]原発関連売られる、東電はS安</title><category>トップ・注目株</category><dirpath>/var/www/mssite/webapp/data/pdf/20110315</dirpath><TimeStamp>201103141700</TimeStamp><FirstPageImg>20110315top.png</FirstPageImg></pagedata>
Param 2: <displayorder>
Basically i want to found (parse) value between start and end tag.
(I know NSXMLParser class but asper i explain this one is existing code and if i changed in code its too much time consuming)
Any suggetion?
With Regards
Pankaj Gadhiya
The code you've posted doesn't look like it's leaking memory -- all the methods you're calling are of the autorelease type (i.e. there's no new, alloc, copy, or retain in the code).
It's probably the code you have that calls retrieveInfo and does something with the result that's leaking memory (e.g. overretaining it). The leaks tool is pointing you at the componentsSeparatedByString because that's where the memory was allocated which was eventually involved in a memory leak.
Can you show us how you call retrieveInfo and what you do with the result?
Btw, what's the point of this nested if?
if([arrRetrive count]!=0){
if ([arrRetrive count]!=1)
It's wasteful, you might as well write this and get the same effect:
if ([arrRetrive count] > 1)
That leak probably means that you're over-retaining the return value. And leaks-tool just shows you the place where it was created.
You are leaking the NSArray when you re-assign a new NSArray inside the if block. The pointer to the original array is lost, which means that the runloop cannot release the memory allocated for the first result. The memory allocated for the second result is released.
You should really use a proper parser... however to address the leak, the following will work.
-(NSString *)retriveInfo:(NSString*)fromstring:(NSString*)searchstring
{
NSArray *arrRetrive = [fromstring componentsSeparatedByString:searchstring];
NSString *result = nil;
if([arrRetrive count]!=0){
if ([arrRetrive count]!=1){
NSString *strDisplayOrder = [arrRetrive objectAtIndex:1];
result = (NSString *)[[strDisplayOrder componentsSeparatedByString:#"<"] objectAtIndex:0];
}
}
return result;
}
What do you do with the object that's returned by this method? [arrRetrive objectAtIndex:0] is likely what's being leaked.
Leaks indicates that line with componentsSeparatedByString: because that's where the strings in the array are allocated. But the array isn't leaked.
Go into Leaks, look at a leaked instance, and click that little arrow button. You'll see all the retains and releases of the leaked object, which should point you to the problem.