NSMutableArray to UITableView - ios

This could be a silly question but I am new to IPhone developing, anyhow I have an NSMutableArray with information loaded from a server. I am trying to put this information on a table. I searched around for some ideas on how to do this and I ran into this code which a lot of people seem to use in order to do this:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [myArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
if (!cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"UITableViewCell"] autorelease];
}
cell.textLabel.text = [myArray objectAtIndex:[indexPath row]];
NSLog(#"Cell is %#", [myArray objectAtIndex:indexPath.row]);
return cell;
}
now my question is inside the if statement it gives me two errors with the autorelease saying: is unavailable and not available on reference counting mode, and arc forbids message send of autorelease, any thoughts?? thanks for the help

The code you have is older code and only works as-is with manual reference counting (MRC). Newer projects use automatic reference counting (ARC) by default. Just remove the call to autorelease and you will be fine.
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"UITableViewCell"];

You are using Automatic Reference Counting, which takes care of memory management for you (for the most part). Remove all references to manual memory management, such as autorelease (and retain, release, etc.), and the app will build. Use this here below:
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"UITableViewCell"];
}

This is also easily done using the freely available Sensible TableView framework. They have something called ArrayOfObjectsSection where you just pass the NSArray to and it will display it automatically, amongst many other stuff (including doning the server fetching for you).

This is a simple tutorial link for add a NSMutableArray into the tableView...Simple Tutorial link..Hope Its useful for you.

Related

Is proper practice to use introspection in this example?

Is proper practice to use introspection in this example?
I'm in a UITableView datasource method tableView:cellForRowAtIndexPath:, and I'm checking for the type of the data source objects, in order to decide which UITableViewCell subclass to use.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
....
id object = [[self getDataSource:tableView] objectAtIndex:[indexPath section]];
if ( [object isKindOfClass:[NSString class]] ||
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
} else if ([object isMemberOfClass:[NSNumber class]]) {
cell = [[[CMAutocompleteTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier andAutocompleteTextField:object] autorelease];
} else if ([object isMemberOfClass:[NSDate class]]) {
cell = [[[CMDateTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier andTextView:object] autorelease];
} else {
cell = [[[CMAutocompleteTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier andAutocompleteTextField:field] autorelease];
}
return cell;
}
I can't see any reason not to check the classes of your data objects, but you should use isKindOfClass: rather than isMemberOfClass:.
The latter checks for an exact match with the class of the receiver, which you're not going to get with the data classes you've got; they're all class clusters. Any given NSString you have, e.g., is going to actually be an __NSCFString. Likewise for NSDate and NSNumber.
Also, you should use ARC.
It's technically ok (with the change to isMemberOfClass: as Josh pointed out).
It's debatable, if it's good style. Does the same tableview really show items of those different classes next to each other? If there are several tableviews, using separate methods/delegates might be more appropriate.
Also, I think you could improve on your method naming. getDataSource is discouraged - "get" has quite a special meaning and is rarely used (for example, in getBytes on NSData). Also you want to get rid of "and" which is just noise.
Finally, is there any reason not to switch to ARC today?

UITableView scrolling madness

I have a table view which gets data from a core data array. When I try to assign the value of the object "Post" to something or NSLog it the table scrolling lags.
Here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CellCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Post *post = [array objectAtIndex:indexPath.row];
// If I comment out the NSLog the scroll is smoothly
NSLog(#"%#", post.title);
// Same thing for the line below
cell.textLabel.text = post.title;
return cell;
}
EDIT:
I'm using StackMob v1.2.0
Using NSLog will surely cause performance issues, especially in methods like cellForRowAtIndexPath which is invoked frequently.
Please check these article for details :
Dropping NSLog in release builds
The Evolution of a Replacement for NSLog
EDIT :
Also your implementation causes the slowness.
You are missing the allocation of tableviewCells.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
First of all you should add the code that "Midhun MP" proposed.
If this doesnt help with the lagging problem...then i suppose post.title must be too heavy to be in that method (because that method gets called too many times)(Please let it not be that post.title uses internet connection to get the string?! Is it?)
Solution:
1)First thing in your app : Create an array2 and put in there all the post.title that u need(every time posts change you shoud update that array2)
2)use this array2 to get the text for the cells : cell.textLabel.textPost=[array2 objectAtIndex:indexPath.row];
3)I cant be 100% sure if NSLog is a problem because i havent tested that(could be..but this should only occur during debug...in release mode you shouldnt have it in there) but its easy to test and see(just comment the NSLog line)
Hope that helps.

Why can't I use the initialized array in tabbed application?

In a tabbed application developed in Xcode 4.2, I found a confusing problem: In one of tabs, there is a tableview to show something like index. So I initialized an array in viewDidLoad() method. for example:
- (void)viewDidLoad
{
NSArray *array = [NSArray arrayWithObjects:#"abc", #"def", #"ghi", #"jkl", #"mno", nil];
self.arrayList = array;
[array release];
[super viewDidLoad];
}
Then I use this arrayList in other methods:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [arrayList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [arrayList objectAtIndex:indexPath.row];
return cell;
}
But Xcode gives me the "EXC_BAD_ACCESS" signal every time I run it. I put some breakpoints, and found that the array was created successfully in viewDidLoad(), but before running the method cellForRowAtIndexPath:(NSIndexPath *)indexPath, it became a freed object. That's the reason why I got that signal and the application crashed. So, how to solve this problem?
Btw, the view controller where the problem occurs is created from UIViewController, not UITableViewController. But I put a table view and linked its datasource and delegate to File's Owner. Does that matter?
You must not release the array. The +arrayWithObjects: convenience method returns an unowned array. You never took ownership of the array, therefore you must not relinquish ownership. Remove the the line [array release] and you will not see this error anymore (at least not for that reason).

Random UITable Delegate crash when selecting filled table

I am creating a simple app to select video urls out of a UITable. I have hooked my data source and delegate to a UIViewController subclass and the table is filled correctly. Also, it recognizes selections and prints to the log.
My issue is that it gets a "EXC_BAD_ACCESS" and crashes when I select a cell. I am looking through the code and the error propagates to this method:
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString* cellIdentifier = #"SelectionIdentifier";
//Errors start happening this next line
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
}
//NSString* str = [[videos objectAtIndex:[indexPath row]] lastPathComponent];
NSString* test = #"test";
[[cell textLabel] setText:test];
return cell;
}
-(void) tableView:(UITableView*)myTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// NSLog(#"Selected!");
}
-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section {
return [videos count];
}
I'm not sure why this error is getting thrown in this method. Any fixes? I double checked to make sure the videos array wasn't nill.
I did another app that used this same method and it doesn't cause these errors.
Any help or suggestions would be greatly appreciated!
Instead of testing if(cell == nil) try using if(!cell). Honestly I'm not sure this is the issue, but after reviewing this I do not think that the error is not actually inside this method (it may somehow be related which is why it brings you here).
If this is only after you select a cell though, why is this method being called?
I think you should also call this method.Because this is preliminary delegate method
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
After seeing your tableView i am not finding any problem at all.Try that may be it will be solve.

EXEC_BAD_ACCESS in UITableView cellForRowAtIndexPath

My UITableView is returning EXEC_BAD_ACCESS, but why!
See this code snippet!
Loading the UITableView works fine, so allXYZArray != nil and is populated!
Then scrolling the tableview to the bottom and back up causes it to crash, as it goes to reload the method cellForRowAtIndexPath
It fails on line:
"NSLog(#"allXYZArray::count: %i", [allXYZArray count]);"
(UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAt
IndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [theTableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
#try
{
if (allXYZArray == nil) {
NSLog(#"nil");
allXYZArray = [ToolBox getMergedSortedDictionaries:allXYZGiven SecondDictionary:allXYZSought];
}
NSLog(#"%i", [indexPath row]);
NSLog(#"allXYZArray::count: %i", [allXYZArray count]);
EXC_BAD_ACCESS means that your program is trying to access a memory address that is invalid or otherwise inaccessible from your process. This most commonly happens when you try send a message to an object that has already been dealloced. So the first step in debugging EXC_BAD_ACCESS is to figure out which object your program was trying to send a message to when the crash happened. Often the answer isn't obvious, in which case, NSZombieEnabled is a great tool for identifying which line of code caused the crash.
In your case you've already determined that the crash happens when you call [allXYZArray count], making allXYZArray our prime suspect. This object is being returned from +[ToolBox getMergedSortedDictionaries:SecondDictionary:], so it's likely that your bug is in the implementation of that method. I would guess that it's returning an object that has already been released instead of autoreleased, as prescribed by the Memory Management Programming Guide for Cocoa. (This is one of the most important documents in the SDK, by the way. I recommend rereading it once a month until its policies and techniques become second nature.)
Ok, reusing a cell, does not guarantee that the cell will be initialized properly:
UITableViewCell *cell = [theTableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell will sometimes be null (especially the first time I guess).
Check cell for null and if so, initialize it properly.
if (cell == nil)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

Resources