I want to update data in tableView and get new data inserted as the new initial rows in a UITableView.
I have two arrays: FileName Array contains data that I get from the server using ParseXM and a temp array used to copy from FileNameArray. I wrote a function UpdateArray to get new data, I copy data from FileNameArray to temp array in ViewDidLoad() and then call UpdateArray; first I remove all entries in FileNameArray, send a request to the server calling ParseXML thereafter, then I compare FileNameArray and temp Array, if FileName arr > temp arr : remove all entries in temp arr and copy from FileName arr to temp arr, then reload data for UITableview but tableView does not show new data in the first row(s).
cellForRowAtIndexPath():
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray* FileNamereversed = [[FileCompletedArray reverseObjectEnumerator] allObjects];
NSArray* UploadTimereversed = [[UploadTimeArray reverseObjectEnumerator] allObjects];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UILabel *FileNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 100, 30)];
FileNameLabel.backgroundColor = [UIColor clearColor];
FileNameLabel.font = [UIFont fontWithName:#"Helvetica" size:16];
FileNameLabel.font = [UIFont boldSystemFontOfSize:16];
FileNameLabel.textColor = [UIColor blackColor];
NSLog(#"Reseversed TEMP array %#",FileNamereversed);
FileNameLabel.text =[FileNamereversed objectAtIndex:indexPath.row];
[cell.contentView addSubview: FileNameLabel];
[FileNameLabel release];
UILabel *UploadTimeLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 20, 300, 25)];
UploadTimeLabel.backgroundColor = [UIColor clearColor];
UploadTimeLabel.font = [UIFont fontWithName:#"Helvetica" size:14];
UploadTimeLabel.textColor = [UIColor grayColor];
UploadTimeLabel.text = [UploadTimereversed objectAtIndex:indexPath.row];
[cell.contentView addSubview: UploadTimeLabel];
[UploadTimeLabel release];
UILabel *CompleteLabel = [[UILabel alloc] initWithFrame:CGRectMake(140, 12, 170, 25)];
CompleteLabel.backgroundColor = [UIColor clearColor];
CompleteLabel.font = [UIFont fontWithName:#"Helvetica" size:14];
CompleteLabel.textColor = [UIColor darkGrayColor];
CompleteLabel.text =#"Completed";
CompleteLabel.textAlignment = NSTextAlignmentRight;
[cell.contentView addSubview: CompleteLabel];
[CompleteLabel release];
}
//[temp removeAllObjects];
// temp = [FileCompletedArray mutableCopy];
return cell;
}
Update Array ():
-(void)updateArray{
[NSThread sleepForTimeInterval:4.0];
[FileCompletedArray removeAllObjects];
...
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:afRequest];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success");
NSString * parsexmlinput = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(#"Response in Loop CompleteView: %#", parsexmlinput); //000400010001
// dispatch_async(dispatch_get_main_queue(), ^{
[self parseXMLFile:parsexmlinput];
NSLog(#"File Completed array: %#", FileCompletedArray);
NSLog(#"File Temp out array: %#", temp);
NSLog(#"File Completed count: %lu",(unsigned long)[ FileCompletedArray count]);
NSLog(#"File Temp out count: %lu", (unsigned long)[temp count]);
// NSLog(#"State: %#", state);
if([FileCompletedArray count ] != [temp count]) // compare 2 array
{
[temp removeallObjects];
temp = [FileCompletedArray mutableCopy];
[_tableView reloadData];
}
else
{
NSLog(#"2 array equal");
}
}
When I call UpdateArray, although server has new data but the two arrays equal each other so my tableView does not update.
Can you show me the solution? Thanks in advance.
editor's remark:
the original wording was close to unintelligible - in correcting I might have missed or misread some aspects. the original author is strongly encouraged to proof-read.
For updating the table view you have to update your array as per your requirement.
You can add object to as: [yourArray insertObject:object atIndex:0]; //for first row.
Then reload table with new array :[yourTable reloadData]
this will work for you.
#V-Xtreme answer is right and another option is...
And also For do this types of work you need to use insertRowsAtIndexPaths:withRowAnimation: Method such like
[self.tableview insertRowsAtIndexPaths:indexPath withRowAnimation:YES ];
Where indexPath contains the row number that you want to add it.
Related
I have a problem: update data in UITableView. I want to get new data from parseXML that response from Server and them update new data to UITableView. **I used beloww code, but it does not show new data on Table View. I wrote a UpdateArray() function to check new data and then I compare 2 Array,if diff [Array count] then I call [tableview reloadData];
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [temp count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 90;
}
- (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];
UILabel *FileNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 100, 30)];
FileNameLabel.backgroundColor = [UIColor clearColor];
FileNameLabel.font = [UIFont fontWithName:#"Helvetica" size:16];
FileNameLabel.font = [UIFont boldSystemFontOfSize:16];
FileNameLabel.textColor = [UIColor blackColor];
NSLog(#"Reseversed TEMP array %#",temp);
FileNameLabel.text =[temp objectAtIndex:indexPath.row];
[cell.contentView addSubview: FileNameLabel];
[FileNameLabel release];
UILabel *UploadTimeLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 20, 300, 25)];
UploadTimeLabel.backgroundColor = [UIColor clearColor];
UploadTimeLabel.font = [UIFont fontWithName:#"Helvetica" size:14];
UploadTimeLabel.textColor = [UIColor grayColor];
UploadTimeLabel.text = [UploadTimeArray objectAtIndex:indexPath.row];
[cell.contentView addSubview: UploadTimeLabel];
[UploadTimeLabel release];
UILabel *CompleteLabel = [[UILabel alloc] initWithFrame:CGRectMake(140, 12, 170, 25)];
CompleteLabel.backgroundColor = [UIColor clearColor];
CompleteLabel.font = [UIFont fontWithName:#"Helvetica" size:14];
CompleteLabel.textColor = [UIColor darkGrayColor];
CompleteLabel.text =#"Completed";
CompleteLabel.textAlignment = NSTextAlignmentRight;
[cell.contentView addSubview: CompleteLabel];
[CompleteLabel release];
}
return cell;
}
UpdateArray()
-(void)updateArray{
while (loop)
{
[NSThread sleepForTimeInterval:4.0];
[FileCompletedArray removeAllObjects];
// [temp removeAllObjects];
....
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:afRequest];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success");
NSString * parsexmlinput = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(#"Response in Loop CompleteView: %#", parsexmlinput);
// dispatch_async(dispatch_get_main_queue(), ^{
[self parseXMLFile:parsexmlinput];
NSLog(#"File Completed array: %#", FileCompletedArray);
NSLog(#"File Temp out array: %#", temp);
NSLog(#"File Completed count: %lu",(unsigned long)[ FileCompletedArray count]);
NSLog(#"File Temp out count: %lu", (unsigned long)[temp count]);
// NSLog(#"State: %#", state);
if([FileCompletedArray count ] != [temp count])
{
[temp removeAllObjects];
temp= [FileCompletedArray mutableCopy];
[_tableView reloadData];
}
else
{
NSLog(#"2 array equal");
}
//});
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", error);
}
];
[httpClient enqueueHTTPRequestOperation:operation];
}
}
Can you help me? Thanks in advance.
I dont See that you call reloadData.
EDIT:
You must check that
1-Temp is having objects i mean that [temp count] is not returning zero.
2-The if condition that checks the two arrays is triggered . I mean that reload data is called.
3-You can make a breakpoint after cell.contetview addsubview and check what the cell contain now?
before you call
[_tableView reloadRowsAtIndexPaths:[_tableView indexPathsForVisibleRows]
withRowAnimation:UITableViewRowAnimationNone];
you have to call
[_tableView beginUpdates];
...
[_tableView endUpdates];
or call
[_tableView reloadData];
If you refresh table view then try this line & check:
[[self mytableview] reloadData];
mytableview is obj of tableview you give here your tableview object.
I have a table view that shows 3 data side by side in table ,lets say A(name) , B(roll no) , C(id).
Now if user do search based on A's (search by name) (table get refreshed with name while searching only) value I want to either hide the content of B & C or they should show the correct value while search is on , not the old value which they got before searching.
I couldn't find the solution how to deal with remaining B & C.kindly suggest
here is my code
- (void) searchTableView
{
NSLog(#"search button is down %#",searchBar.text);
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
if(SearchQuery==1)
{
[searchArray addObjectsFromArray:[entityArray valueForKey:#"Name"]];
}
if(SearchQuery==2)
{
[searchArray addObjectsFromArray:[entityArray valueForKey:#"IC"]];
}
for (NSString *sTemp in searchArray)
{
NSLog(#"copyListOfItems in search -%#",copyListOfItems);//final array for names
NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
[copyListOfItems addObject:sTemp];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSManagedObject *object = (NSManagedObject *)[entityArray objectAtIndex:indexPath.row];
NSString *CellIdentifier = #"Cell";
int indicator = UITableViewCellAccessoryNone;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
mainLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 50.0)] autorelease];//220
mainLabel.tag = MAINLABEL_TAG;
[mainLabel setFont:[UIFont fontWithName:#"Helvetica-Bold" size:18]];//Palatino-BoldItalic
mainLabel.textAlignment = UITextAlignmentLeft;
mainLabel.textColor = [UIColor blackColor];
secondLabel = [[[UILabel alloc] initWithFrame:CGRectMake(313.0, 9.0, 200.0, 25.0)] autorelease];//83
secondLabel.tag = SECONDLABEL_TAG;
smallSystemFontSize]]];
[secondLabel setFont:[UIFont fontWithName:#"Helvetica" size:18]];
secondLabel.textAlignment = UITextAlignmentLeft;
secondLabel.textColor = [UIColor blackColor];
[cell.contentView addSubview:secondLabel];
//// 3rd labl display
thirdLabel = [[[UILabel alloc] initWithFrame:CGRectMake(560.0, 9.0, 250.0, 25.0)] autorelease];//83
thirdLabel.tag = THIRDLABEL_TAG;
//thirdLabel.font = [UIFont systemFontOfSize:13.0];
[thirdLabel setFont:[UIFont fontWithName:#"Helvetica" size:18]];//Palatino-BoldItalic
thirdLabel.textAlignment = UITextAlignmentLeft;
thirdLabel.textColor = [UIColor blackColor];
[cell.contentView addSubview:thirdLabel];
}
if(searching)
{
NSLog(#" seacrh List in table view =%#",[copyListOfItems objectAtIndex:indexPath.row]);
// NSString *s=[object valueForKey:#"Name"];
NSLog(#"copyListOfItems length ---------%d",[copyListOfItems count]);
cell.textLabel.text =[copyListOfItems objectAtIndex:indexPath.row] ;
if(SearchQuery==2)
{
secondLabel.text=#"kk";// not working
secondLabel.alpha=1; // this is not working i cant upadate
}
}
else
{
if(self.entityName == #"Parent")
{
{
indicator = UITableViewCellAccessoryDisclosureIndicator;
CellIdentifier = #"CellWithDisclosure";
}
}
if(SearchQuery==2)
{
cell.textLabel.text =[object valueForKey:#"IC"] ;
secondLabel = (UILabel *)[cell.contentView viewWithTag:SECONDLABEL_TAG];
thirdLabel = (UILabel *)[cell.contentView viewWithTag:THIRDLABEL_TAG];
NSLog(#"sex is %# ",[object valueForKey:#"Name"]);
secondLabel.text=[object valueForKey:#"Name"] ;
secondLabel.alpha=0;
thirdLabel.text=[object valueForKey:#"roll"] ;
}
I have a UItableview with array of contents in it.There are two array ,I want to switch the array by using a button click.
My code is
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
tab.backgroundColor = [UIColor clearColor];
tab.separatorColor = [UIColor clearColor];
cell.chapterAndVerse.text = [NSString stringWithFormat:#"%d",indexPath.row+1];
cell.chapterAndVerse.font = [UIFont fontWithName:#"Georgia" size:17.0];
cell.chapterAndVerse.frame=CGRectMake(0, 10, 30.0, 20.0);
cell.textLabel.text = [NSString stringWithFormat:#" %#",[delegate.allSelectedVerseMalayalam objectAtIndex:indexPath.row]];
cell.textLabel.font = [UIFont fontWithName:#"testfont" size:18];
cell.backgroundColor = [UIColor clearColor];
}
my array is delegate.allSelectedVerseMalayalam ,I want this array to be changed with delegate.allSelectedVerseEnglish in button click.When the button for english is clicked by the user it changes the tableviewcontent(my table names is tab)to delegate.allSelectedVerseEnglish .How is this possible.Plese help me to figure out from this problem.
Thanks in advance.
EDIT:
- (void)viewDidLoad {
NSLog(#"%#", delegate.allSelectedVerseMalayalam);
tempArray = [[NSMutableArray alloc] init];
[tempArray addObjectsFromArray:delegate.allSelectedVerseMalayalam];
NSLog(#"%#", tempArray);
[self.tab reloadData];
}
-(IBAction)_clickbtndefaultlnguageset:(id)sender
{
[tempArray removeAllObjects];
[tempArray addObjectsFromArray:delegate.allSelectedVerseHindi];
[self.tab reloadData];
}
in tableview
cell.chapterAndVerse.text = [NSString stringWithFormat:#"%d",indexPath.row+1];
cell.chapterAndVerse.font = [UIFont fontWithName:#"Georgia" size:17.0];
cell.chapterAndVerse.frame=CGRectMake(0, 10, 30.0, 20.0);
cell.textLabel.text = [NSString stringWithFormat:#" %#",[tempArray objectAtIndex:indexPath.row]];
// cell.textLabel.textColor = [UIColor darkGrayColor];
cell.textLabel.font = [UIFont fontWithName:#"testfont" size:18];
cell.backgroundColor = [UIColor clearColor];
do one thing take one extra array and allocated it
define in your source file .h file
NSMutableArray *tempArray;
-(void)viewDidLoad{
//NSLog(#"%#", your Array);
tempArray = [[NSMutableArray alloc] init];
[tempArray addObjectsFromArray:yourfirstarray];
NSLog(#"%#", tempArray);
[self.tableview reloadData];
}
after prees the button
-(void)pressedBtn{
//NSLog(#"%#", your Array);
[tempArray removeAllObjects];
[tempArray addObjectsFromArray:yoursecondArray];
[self.tableView reloadData];
}
use this temp array into table array
So I am writing an app to read an rss feed, and display the contents in a tableview. It also lets the user play back mp3s that it finds for each item. Anyway the app seemed to be running fine before I started adding new views. Now every time I come back from a view and scroll around a bit, I get "Program received signal "SIGABRT"" or something similar.
here's most of the program:
- (IBAction)playAction:(id)sender
{
// Get row
UIButton *senderButton = (UIButton *)sender;
UITableViewCell *buttonCell =
(UITableViewCell *) [[senderButton superview] superview];
NSInteger buttonRow = [[self.tableView
indexPathForCell:buttonCell] row];
// Entry for row
RSSEntry *senderEntry = [_allEntries objectAtIndex:buttonRow];
// This is where _allEntries gets filled
- (void)requestFinished:(ASIHTTPRequest *)request {
[_queue addOperationWithBlock:^{
NSError *error;
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:[request responseData]
options:0 error:&error];
if (doc == nil)
{
NSLog(#"Failed to parse %#", request.url);
}
else
{
NSMutableArray *entries = [NSMutableArray array];
[self parseRss:doc.rootElement entries:entries];
if ([_allEntries count] > 0) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// Update
int i=0;
while (![[[_allEntries objectAtIndex:i] articleUrl] isEqualToString:[[entries objectAtIndex:i] articleUrl]])
{
[_allEntries insertObject:[entries objectAtIndex:i] atIndex:0];
i++;
}
[self.tableView reloadData];
}];
}
else
{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
for (RSSEntry *entry in entries)
{
[_allEntries addObject:entry];
}
NSLog(#"entries:%d", [_allEntries count]);
[self.tableView reloadData];
}];
}
}
}];
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"View did load");
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh
target:self
action:#selector(refreshButton:)];
pauseImage = [UIImage imageNamed:#"pause_circle_small.png"];
playImage = [UIImage imageNamed:#"play_circle_small.png"];
player = nil;
isPlaying = NO;
self.title = #"Feed";
self.allEntries = [NSMutableArray array];
self.queue = [[[NSOperationQueue alloc] init] autorelease];
self.feed = [[NSString alloc] initWithString:#"http://site.org/rss/"];
[self refresh];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [_allEntries count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UILabel *mainLabel, *secondLabel;
UIButton *playBtn;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
mainLabel = [[[UILabel alloc] initWithFrame:CGRectMake(42.0, 5.0, 250.0, 20.0)] autorelease];
mainLabel.tag = MAINLABEL_TAG;
mainLabel.font = [UIFont fontWithName:#"Arial-BoldMT" size:18.0];
mainLabel.textAlignment = UITextAlignmentLeft;
mainLabel.textColor = [UIColor blackColor];
mainLabel.highlightedTextColor = [UIColor whiteColor];
[cell.contentView addSubview:mainLabel];
secondLabel = [[[UILabel alloc] initWithFrame:CGRectMake(42.0, 27.0, 250.0, 15.0)] autorelease];
secondLabel.tag = SECONDLABEL_TAG;
secondLabel.font = [UIFont fontWithName:#"ArialMT" size:14.0];
secondLabel.textAlignment = UITextAlignmentLeft;
secondLabel.textColor = [UIColor colorWithRed:222.0/255.0 green:95.0/255.0
blue:199.0/255.0 alpha:1.0];
secondLabel.highlightedTextColor = [UIColor whiteColor];
[cell.contentView addSubview:secondLabel];
playBtn = [UIButton buttonWithType:UIButtonTypeCustom];
playBtn.tag = PLAYBTN_TAG;
playBtn.frame = CGRectMake(2.0, 6.0, playImage.size.width, playImage.size.height);
[playBtn setBackgroundImage:playImage forState:UIControlStateNormal];
//[playBtn setBackgroundImage:playImage forState:UIControlStateHighlighted];
[playBtn addTarget:self action:#selector(playTapped:)
forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:playBtn];
}
else
{
mainLabel = (UILabel *)[cell.contentView viewWithTag:MAINLABEL_TAG];
secondLabel = (UILabel *)[cell.contentView viewWithTag:SECONDLABEL_TAG];
playBtn = (UIButton *)[cell.contentView viewWithTag:PLAYBTN_TAG];
}
// Alternate bg color
if (indexPath.row%2 == 0) {
UIColor *altColor = [UIColor colorWithRed:230.0/255.0 green:230.0/255.0
blue:230.0/255.0 alpha:1];
mainLabel.backgroundColor = altColor;
secondLabel.backgroundColor = altColor;
}
else
{
UIColor *altColor = [UIColor colorWithRed:255.0 green:255.0
blue:255.0 alpha:1];
mainLabel.backgroundColor = altColor;
secondLabel.backgroundColor = altColor;
}
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
NSLog(#"Entry: %#", entry);
// Manage play button
if (entry == currEntry)
{
if(isPlaying)
{
[playBtn setBackgroundImage:pauseImage forState:UIControlStateNormal];
}
else
{
[playBtn setBackgroundImage:playImage forState:UIControlStateNormal];
}
}
else
[playBtn setBackgroundImage:playImage forState:UIControlStateNormal];
mainLabel.text = entry.articleTitle;
secondLabel.text = entry.articleArtist;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
DetailView *detailViewController = [[DetailView alloc] initWithNibName:#"DetailedView" bundle:[NSBundle mainBundle]];
RSSEntry *entry = [_allEntries objectAtIndex:[indexPath row]];
[self.navigationController pushViewController:detailViewController animated:YES];
detailViewController.songTitle.text = entry.articleTitle;
detailViewController.artistName.text = entry.articleArtist;
[entry release];
[detailViewController release];
}
- (void)dealloc
{
[player release];
player = nil;
[_queue release];
_queue = nil;
[_feed release];
_feed = nil;
[_allEntries release];
_allEntries = nil;
[super dealloc];
}
#end
Please Dont release any #synthesize variable. You should only release it in dealloc method
It's a wild guess, but you don't retain the images that you get in viewDidLoad:
pauseImage = [UIImage imageNamed:#"pause_circle_small.png"];
playImage = [UIImage imageNamed:#"play_circle_small.png"];
Either use retaining property and dot syntax or send each a retain.
AHAA!!! I was setting my RSSEntry to autorelease before putting them in the _allEntries array. They were getting dealloc'd when I changed views. Don't do that. Thanks for the help everyone. That was so simple, I feel dumb now.
please don't release the self.feed and also when unload or dealloc the view at that time put delegate nil means
tableview.delegate = nil;
this one is the main thing check after this i think u don't nil the delegate of tableview.
without line where you get crash its hard to tell, but most likely you accessing some object what was dealloc'ed
most likely its here
self.feed = [[NSString alloc] initWithString:#"http://site.org/rss/music"];
[self.feed release];
you releasing objects right away, but its hard to tell without knowing if you have retained property
I'm newbie to objective-c . My problem is slow navigation between controllers.
When I jump from one controller to another it's really slow, because it gets data from the service, parse it and then display it. All this takes around 4-5 secs.
Now I've put all this data fetching in loadView of my DetailController. Is there anyway that I show the controller first and then display the data. Because as of now, when I select a row on my root controller, it shows activity and stays on root controller and then it navigates to the DetailController.
So it loads the data first and then displays it. Is there anyway that I can reverse this process, show the controller first and then display it..
this is what I'm doing
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DataCollection *collection = [DataCollection sharedObject];
Product *tempProduct = [[collection popularProducts] objectAtIndex:row] ;
ProductDetailViewController *tempProductDetail = [[ProductDetailViewController alloc] init];
tempProductDetail.homeViewProduct = tempProduct;
[tempProductDetail release];
}
and then the Detail Controller
- (void)loadView {
[super loadView];
// here's all the data loading and parsing ... which takes time
}
//Here's the method for downloading the data, I'm using a REST service to get all the data.
- (void) getProductData:(NSString*)productId{
NSMutableString *specificURL = [[NSMutableString alloc] initWithString:#"GetProductPage?id="];
[specificURL appendFormat:#"%#",productId];
[specificURL appendFormat:#"&dataSources=&accountId=&companyId=&version=1&cultureCode=sv¤cyId=2&format=json"];
NSDictionary *serverCategories = [[NSDictionary alloc] initWithDictionary:[appRequestController proceesRequest:specificURL]];
NSArray *categories = [[[serverCategories objectForKey:#"DataSources"] objectAtIndex:0] objectForKey:#"Items"];
[serverCategories release];
if ([[productsArray objectAtIndex:j] objectForKey:#"Name"] != [NSNull null]) {
[product setProductName:[[productsArray objectAtIndex:j] objectForKey:#"Name"]];
}
else {
[product setProductName:#""];
}
if ([[productsArray objectAtIndex:j] objectForKey:#"ThumbnailImage"] != [NSNull null]) {
[product setProductImage:[[productsArray objectAtIndex:j] objectForKey:#"ThumbnailImage"]];
}
else {
[product setProductImage:#""];
}
if ([[productsArray objectAtIndex:j] objectForKey:#"Price"] != [NSNull null]) {
[product setProductPrice:[[productsArray objectAtIndex:j] objectForKey:#"Price"]];
}
else {
[product setProductPrice:#""];
}
[[collection popularProducts] addObject:product];
[product release];
}
I've copy pasted junks of the code so that you can get an idea how I'm getting the data. Below is the code for cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *MyIdentifier = #"mainMenuIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
[cell setSelectedBackgroundView:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"highlightstrip.png"]]];
}
UILabel *productNameLbl = [[UILabel alloc] initWithFrame:CGRectMake(90, 8, 200,10)];
[productNameLbl setText:[NSString stringWithString:[[[[DataCollection sharedObject] popularProducts]objectAtIndex:indexPath.row] productName]]];
[productNameLbl setFont:[UIFont boldSystemFontOfSize:12.0]];
[cell addSubview:productNameLbl];
[productNameLbl release];
UILabel *productSubLbl = [[UILabel alloc] initWithFrame:CGRectMake(90, 22, 190,40)];
[productSubLbl setText:[NSString stringWithString:[[[[DataCollection sharedObject] popularProducts]objectAtIndex:indexPath.row] productSubHeader]]];
[productSubLbl setTextColor:[UIColor colorWithRed:102.0/255.0 green:102.0/255.0 blue:102/255.0 alpha:1.0]];
productSubLbl.lineBreakMode = UILineBreakModeWordWrap;
productSubLbl.numberOfLines = 3;
[productSubLbl setFont:[UIFont fontWithName:#"Arial" size:10]];
[cell addSubview:productSubLbl];
[productSubLbl release];
NSMutableString *url = [[NSMutableString alloc] initWithString:#""];
NSString *baseImageURL = #"http://samplesite.com/";
NSString *imagePath = [NSString stringWithString:[[[[DataCollection sharedObject] popularProducts]objectAtIndex:indexPath.row] productImage]];
[url appendString:baseImageURL];
[url appendString:imagePath];
NSURL *imageURL = [NSURL URLWithString:url];
NSData *data = [NSData dataWithContentsOfURL:imageURL];
UIImage *img = [[UIImage alloc] initWithData:data cache:NO];
UIImageView *imageView = [[UIImageView alloc] initWithImage:img];
[imageView setFrame:CGRectMake(10, 10, 70, 70)];
[cell addSubview:imageView];
[imageView release];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
Pass the url or product id to the detail view. Inside the viewDidLoad of the ProductDetail, create a background thread to retrieve your data. When you background thread finish, it will notify your ProductDetail controller with the detail. At that time, you update your ProductDetailView.
To get your data on a background thread you can use
NSThread
NSOperation
Pass the row into your ProductDetailViewController, and do the fetch in it's viewDidLoad method. You might also want to show a spinner (UIActivityIndicator), and you definitely should read up on background threads.
To make view available to user and loading data after some time you can use NSTimer.
Just have a NSTimer method which will be called in viewDidLoad method as
[NSTimer scheduledTimerWithTimeInterval:<#(NSTimeInterval)ti#> target:<#(id)aTarget#> selector:<#(SEL)aSelector#> userInfo:<#(id)userInfo#> repeats:<#(BOOL)yesOrNo#>]
put some time interval which will be calling your loading method after that.
Hope this helps.