Application Crash on Fast switching between UISegment - iphone

I have a segment and a table view, I have to reload the data in the table view its working but when i switch the segment buttons fast then application crashes.
On segment i have three buttons and on their action I am triggering a request to a url and fetching the json from that url (3 different urls resp. and returns 10, 17 and 8 results in json).
I have a custom table cell which have the images in it and i am trying to lazily load theose images.
In JSON result each object of json have various keys in it like name, id, imageurl etc.
the id is unique throughout the application and I am trying to load the images and save the images in local memory based on that unique id, so that i can show the cashed images and no need to redownload the images on segment change because some enteries on all three segments are same.
Here is my complete code
- (IBAction)segmentedControlIndexChanged {
NSString *offerRequestUrl = nil;
switch (self.mySegment.selectedSegmentIndex) {
case 0:
offerRequestUrl = #"url_one";
self.feedRequestUrl = [NSURL URLWithString:offerRequestUrl];
break;
case 1:
offerRequestUrl = #"url_two";;
self.feedRequestUrl = [NSURL URLWithString:offerRequestUrl];
break;
case 2:
offerRequestUrl = #"url_three";;
self.feedRequestUrl = [NSURL URLWithString:offerRequestUrl];
break;
default:
break;
}
[self parseJSONWithURL:self.feedRequestUrl];
}
- (void) parseJSONWithURL:(NSURL *) jsonURL
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData* data = [NSData dataWithContentsOfURL: jsonURL];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
- (void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData
options:kNilOptions
error:&error];
self.feedsArray = [json objectForKey:#"result"];
[self.myTableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int count = self.feedsArray.count;
// if there's no data yet, return enough rows to fill the screen
if (count == 0)
{
return 1;
}
return count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// customize the appearance of table view cells
//
static NSString *CellIdentifier = #"MyTableCell";
static NSString *PlaceholderCellIdentifier = #"PlaceholderCell";
// add a placeholder cell while waiting on table data
int nodeCount = [self.feedsArray count];
if (nodeCount == 0 && indexPath.row == 0)
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:PlaceholderCellIdentifier];
cell.detailTextLabel.textAlignment = UITextAlignmentCenter;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
cell.detailTextLabel.text = #"Loading . . .";
[self performSelector:#selector(checkAndDisplayAlert) withObject:self afterDelay:10.0];
return cell;
}
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (nodeCount > 0)
{
// Configure the cell...
cell.carImageView.image = [UIImage imageNamed:#"Placeholder"]; //acts as default image
if([self.imageDict valueForKey:[NSString stringWithFormat:#"%#", self.feedsArray[indexPath.row][#"id_str"]]]==nil)
{
[NSThread detachNewThreadSelector:#selector(displayingSmallImage:) toTarget:self withObject:indexPath];
} else {
cell.carImageView.image = [self.imageDict valueForKey:[NSString stringWithFormat:#"%#", self.feedsArray[indexPath.row][#"id_str"]]];
}
cell.imageView.clipsToBounds = YES;
cell.titleLabel.text = self.feedsArray[indexPath.row][#"title_key"];
}
return cell;
}
- (void) displayingSmallImage:(NSIndexPath *)indexPath
{
NSString *imageUrl = self.feedsArray[indexPath.row][#"icon_url"];
NSURL *url = [NSURL URLWithString:imageUrl];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
if(image == nil)
{
image = [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"Placeholder"]];
}
[self.imageDict setObject:image forKey:[NSString stringWithFormat:#"%#", self.feedsArray[indexPath.row][#"id_str"]]];
[self performSelectorOnMainThread:#selector(imageReceived:) withObject:indexPath waitUntilDone:NO];
}
- (void) imageReceived:(NSIndexPath *)indexPath
{
UIImage *image = (UIImage *)[self.imageDict objectForKey: [NSString stringWithFormat:#"%#", self.feedsArray[indexPath.row][#"id_str"]]];
UIImageView *imgs = (UIImageView *)[[self.myTableView cellForRowAtIndexPath:indexPath] viewWithTag:IMG_TAG];
[imgs setImage:image];
[self.myTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
- (void) checkAndDisplayAlert
{
if (!self.feedsArray && self.isAlertPresent == NO) {
UIAlertView *nilAlert = [[UIAlertView alloc] initWithTitle:#"Sorry!"
message:#"No result returned from server."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[nilAlert setTag:kNilAlertTag];
self.isAlertPresent = YES;
[nilAlert show];
}
}
The main things I have to do is
lazily download the images
cache the images in local memory based on unique ID
Check the cashed images dictionary for already downloaded image and display it
If possible save these downloaded images in the local memory (nsuserdefaults etc) so that if user restart the app then also images are there and can be displayed based on their unique ID and no need to download again.
Any help would be appreciated.

Please post the error log, if it is array out of bounds exception I suspect these two methods
- (void)fetchedData:(NSData *)responseData & your tableViewDatasource
To find which line of code causes this crash do this. Go to break points tab on the left side and click + in the bottom.
Then you would get something like this:
Just hit done, run your code again and tell us which line caused the exception.
I understood your problem, why do you want to take the URL from the array in this function
- (void) displayingSmallImage:(NSIndexPath *)indexPath
you could pass the Url to load to that function, from cellForRowAtIndex like this:
NSArray *argsToPass=[NSArray arrayWithObjects:indexPath,self.feedsArray[indexPath.row][#"icon_url"]];
[NSThread detachNewThreadSelector:#selector(displayingSmallImage:) toTarget:self withObject:argsToPass];
and your function is modified as:
- (void) displayingSmallImage:(NSArray *)args
{
if([args count] == 0)
{
NSString *imageUrl = [args objectAtIndex:1];
NSIndexPath *indexPath=[args objectAtIndex:0];
NSURL *url = [NSURL URLWithString:imageUrl];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
if(image == nil)
{
image = [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"Placeholder"]];
}
[self.imageDict setObject:image forKey:[NSString stringWithFormat:#"%#", self.feedsArray[indexPath.row][#"id_str"]]];
[self performSelectorOnMainThread:#selector(imageReceived:) withObject:indexPath waitUntilDone:NO];
}
}

you can set self.view.userInteractionEnabled=NO when you are sending request to server.
and when u get the data just enable the user interaction .so that multiple requests are avoided.

Related

Slow UITableView with Facebook Image

I have a uitableview and each cells have an image from facebook image profile and 2 uilabels (from singleton, not an internet request)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
static NSString *CellIdentifier = #"MenuCell";
MenuCellViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[MenuCellViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//Singleton
DataModel *m = [DataModel getModel];
switch ([indexPath section]) {
case 0: //Only Header
break;
case 1: //My cells
{
//If footer - set footer background
if (indexPath.row == [tableView numberOfRowsInSection:indexPath.section] - 1){
[cell setBackgroundView:[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"imgFooter.png"]]];
//Else - set normal cell background
} else {
[cell setBackgroundView:[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"img.png"]]];
}
//Get Facebook image
strForImg = [[NSString alloc] initWithFormat:#"https://graph.facebook.com/%#/picture?type=square",[[[m list] objectAtIndex:indexPath.row] objectForKey:#"id"]];
url =[NSURL URLWithString:strForImg];
img = [UIImage imageWithData: [NSData dataWithContentsOfURL:url]];
[cell.imgProfile setImage:img];
//Set some text (uilabels)
cell.lblNom.text = [[[m list] objectAtIndex:indexPath.row] objectForKey:#"name"];
cell.lblTour.text = [[[m list] objectAtIndex:indexPath.row] objectForKey:#"description"];
break;
}
}
}
This code is very slow and freezes the tableview as it loads from facebook the profile images of each cell dynamically.
I tried doing with a dispatch like this
case 1://My cells
{
if (indexPath.row == [tableView numberOfRowsInSection:indexPath.section] - 1){
[cell setBackgroundView:[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"imgFooter.png"]]];
} else {
[cell setBackgroundView:[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"img.png"]]];
}
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
dispatch_sync(dispatch_get_main_queue(), ^{
strForImg = [[NSString alloc] initWithFormat:#"https://graph.facebook.com/%#/picture?type=square",[[list objectAtIndex:indexPath.row] objectForKey:#"id"]];
url =[NSURL URLWithString:strForImg];
img = [UIImage imageWithData: [NSData dataWithContentsOfURL:url]];
[cell.imgProfile setImage:img];
});
});
cell.lblNom.text = [[[m list] objectAtIndex:indexPath.row] objectForKey:#"name"];
cell.lblTour.text = [[[m list] objectAtIndex:indexPath.row] objectForKey:#"description"];
break;
}
The speed has slighty increased but it is still FREEZING when scrolling.
Is my dispatch not correct ? (I have just discovered it, maybe it is not well used).
Or is there any better method ?
I like the facebook friend picker. It puts a default profile image and refreshes the correct image profile when it is received from internet. How is this magic done ? :)
Fix this block:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
strForImg = [[NSString alloc] initWithFormat:#"https://graph.facebook.com/%#/picture?type=square",[[list objectAtIndex:indexPath.row] objectForKey:#"id"]];
url =[NSURL URLWithString:strForImg];
img = [UIImage imageWithData: [NSData dataWithContentsOfURL:url]];
dispatch_sync(dispatch_get_main_queue(), ^{
[cell.imgProfile setImage:img];
});
});

Cancel Selector in UITableViewCell

I have scenario that in which i am using selector in TableViewCell as bellow and when I click on back button in my view I want to cancel that selector and I am sending dictionary as object in Selector
My code is as bellow
In Header File
NSMutableDictionary* photoDict;
NSMutableDictionary* dictImages;
In .M file
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell==nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
[[NSBundle mainBundle]loadNibNamed:#"MyCellNib" owner:self options:Nil];
cell = detailChainObj;
}
NSString* avatarURL =#"image_Url"; //Any url of image for cell.
NSString *key =[[NSString alloc] initWithFormat:#"Key%d%d",indexPath.section,indexPath.row];
dictImages = [NSDictionary dictionaryWithObjectsAndKeys:imageViewCell,#"Img",imgURL,#"imgURL",key,#"key", nil];
[self performSelectorInBackground:#selector(DownloadLinkzImageOfUser:) withObject:dictImages];
if([photoDic valueForKey:keyAvt])
{
NSData* data = (NSData*)[photoDic valueForKey:key];
imageViewCell.image = [UIImage imageWithData:data];
}
else
{
[self performSelectorInBackground:#selector(DownloadImagesForCell:) withObject:dictImages];
}
}
//
-(void)DownloadImagesForCell:(NSDictionary *)result
{
UIImageView* img = (UIImageView*)[result objectForKey:#"Img"];
NSString* urlAvt = [result valueForKey:#"imgURL"];
if([urlAvt isEqualToString:#"No Image"])
{
img.image = [UIImage imageNamed:#"noimg.png"];
}
else
{
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imgURL]];
img.image = [UIImage imageWithData:data];
[photoDic setValue:data forKey:[NSString stringWithFormat:#"%#",[result valueForKey:#"key"]]];
}
}
Now I want to cancel this selecter when I press back button
and please keep in mind that I have already use
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(DownloadImagesForCell:) object:dictImages];
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsobject_Class/Reference/Reference.html
I guess this method works for performSelector:withObject:afterDelay: only.

Image Loading Animation issue using GCD

Hi I'm using GCD to load image in the uitableview . Now, the problem is image animation. I called three images from server it loads into the cell but i got 3 problems
1) Single image is repeated in all three cells
2) first and last cell images blinking and changing
3) when the image changed, it is repeated in all cells.
Even though i gave animation none still it animates i.e. Blinking
Code:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
[imageArray retain];
//get a dispatch queue
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//this will start the image loading in bg
dispatch_async(concurrentQueue, ^{
NSData *image = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:[imageArray objectAtIndex:indexPath.row]]];
//this will set the image when loading is finished
dispatch_async(dispatch_get_main_queue(), ^{
cell.imageView.image = [UIImage imageWithData:image];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
});
});
return cell;
}
You should not download images in this place.
If You don't have too many rows, do this in eg. viewDidLoad and save downloaded images to new mutable array.
Something like this:
- (void) viewDidLoad {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
dispatch_async(queue, ^{
int row = 0;
self.thumbnails = [NSMutableArray array];
for (NSString *imageURLString in imageArray) {
//Your way of download images
NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imageURLString]];
UIImage *image = [UIImage imageWithData:imageData];
dispatch_async(dispatch_get_main_queue(), ^{
[self.thumbnails addObject:image];
NSArray *indexes = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:row inSection:1]];
[self.tableViewOutlet reloadRowsAtIndexPaths:indexes withRowAnimation:UITableViewRowAnimationNone];
});
row++;
}
});
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.thumbnails && [self.thumbnails count] > indexPath.row) {
cell.attachmentImageView.image = [self.thumbnails objectAtIndex:indexPath.row];
} else {
cell.attachmentImageView.image = nil;
}
}

Help me on loading the images on table view using NSOperationQueue

Kindly look the below code..i found from web
- (void) loadData {
NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
selector:#selector(loadDataWithOperation) object:nil];
[queue addOperation:operation];
[operation release];
}
- (void) loadDataWithOperation {
NSURL *dataURL = [NSURL URLWithString:#"http://icodeblog.com/samples/nsoperation/data.plist"];
NSArray *tmp_array = [NSArray arrayWithContentsOfURL:dataURL];
for(NSString *str in tmp_array) {
[self.array addObject:str];
}
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:YES];
}
- (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 setText:[self.array objectAtIndex:indexPath.row]];
return cell;
}
I have found the above code which loads the text from the web without any problem.( i mean gui is not hanging ).like wise i want to load images into the table view.for that i have wriiten the below code.
- (void) loadDataWithOperation {
NSString *Img_id, *Img_name, *DynamicImgUrl;
Img_id = xmltag.equip_id;
Img_name = xmltag.image;
DynamicImgUrl = [NSString stringWithFormat:#"http://test.com/pics/equipment/%#/%#",Img_id, Img_name];
NSURL *ImageUrl = [NSURL URLWithString:DynamicImgUrl];
//UIImage *image = [UIImage imageWithData: [NSData dataWithContentsOfURL:ImageUrl]];
NSArray *tmp_array = [NSArray arrayWithContentsOfURL:ImageUrl];
for(NSString *str in tmp_array) {
[self.array addObject:str];
}
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:YES];
}
Am i correct here? how can i go with adding into the table view...
Kindly help me out...
U are seeking to display images on Tableview from URL, when u download image from url we need to consider some issues, it will freeze ur table view if u goahead with ordinary loading image.
i suggest u look at LazyLoading image
u see this link http://developer.apple.com/library/ios/#samplecode/LazyTableImages/Introduction/Intro.html
Download this sample and get to know the things

lazy loading images in UITableView iPhone SDK

I need to implement the lazy loading concept for the images in my tableview, so that the user will be provided with the textual data initially and later the images.
How can i implement this in to my app.. help needed.. please
Thanks in advance
Shibin
What i have created for a project of mine works as follows;
Extend the UITableViewCell class by a category in "UITableViewCell+Async.h"
(See some examples if you are not sure what the category thing in Obj C is)
#interface UITableViewCell (Async)
-(void)loadAsyncImage:(NSString*)url withIndex:(NSInteger)index inWidth:(NSInteger)width inHeight:(NSInteger)height;
-(void)loadAsyncBackground:(NSMutableArray*)parameters;
#end
And then in the implementation file "UITableViewCell+Async.m"
#import "UITableViewCell+Async.h"
#implementation UITableViewCell (Async)
-(void)loadAsyncImage:(NSString*)url
withIndex:(NSInteger)index
inWidth:(NSInteger)width
inHeight:(NSInteger)height {
NSMutableArray* parameters = [NSMutableArray arrayWithCapacity:2];
[parameters addObject:url];
[parameters addObject:[NSNumber numberWithInteger:index]];
[parameters addObject:[NSNumber numberWithInteger:width]];
[parameters addObject:[NSNumber numberWithInteger:height]];
self.imageView.tag = index;
[self performSelectorInBackground:#selector(loadAsyncBackground:) withObject:parameters];
}
-(void)loadAsyncBackground:(NSMutableArray*)parameters {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString* url = [parameters objectAtIndex:0];
NSInteger index = [[parameters objectAtIndex:1] integerValue];
NSInteger width = [[parameters objectAtIndex:2] integerValue];
NSInteger height = [[parameters objectAtIndex:3] integerValue];
UIImage* image = [Utils getImageResized:url inSize:CGSizeMake(width, height)];
if (self.tag==index) {
self.imageView.image = image;
[self setNeedsLayout];
}
[pool release];
}
#end
This basically adds a functionality to the UITableViewCell to load an image in a new background thread, resize the image and set it to the imageview. Checking the tag is added to see if the cell is still waiting for the image, since it can be re-used and another thread for the image could be downloading another image for that re-used cell...
The function in the above code with the signature of;
+(UIImage*)getImageResized:(NSString*)url inSize:(CGSize)size;
checks a local cache of images, downloads the image from the web if not in the cache, saves it to local cache, resizes the image in the given size and returns the image, all done in a sync(blocking) method call. Since this is already the background thread, no harm blocking it for this operation. When the method returns the image, it is set to the cell's imageview if it still has the same tag(not re-used for some other row)
In the cellForRowAtIndexPath method you can add the new category and you should be done;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"......."];
if (cell == nil) {
................
}
................
[cell loadAsyncImage:deal.logo withIndex:indexPath.row inWidth:40 inHeight:40];
................
return cell;
}
Do you mean this
http://developer.apple.com/iphone/library/samplecode/LazyTableImages/Introduction/Intro.html
I used ASINetworkQueue for lazy loading.
In .h file
#import "ASINetworkQueue.h"
and define a variable
//array contains url address of images and a variable of ASINetworkQueue;
NSMutableArray *arrImg;
ASINetworkQueue *queue;
In .m file
static int rowNo = 0;
- (void)downloadImages{
if(queue == nil){
queue = [[[ASINetworkQueue alloc] init] autorelease];
}
for(NSString* urlString in arrImg)
{
NSURL *url = [NSURL URLWithString:urlString];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request setDidFinishSelector:#selector(requestDone:)];
[request setDidFailSelector:#selector(requestWentWrong:)];
[queue addOperation:request];
}
[queue go];
}
- (void)requestDone:(ASIHTTPRequest*)req{
for (int i = 0; i < [arrImg count]; i++) {
NSMutableString *d = [[NSMutableString alloc] init];
d = [arrImg objectAtIndex:i];
//comparing the url to get correct row no of cell
if([[req.url absoluteString] isEqualToString:d]){
rowNo = i;
break;
}
}
//creating a cell with rowNo
NSIndexPath *index = [NSIndexPath indexPathForRow:rowNo inSection:0];
UITableViewCell *cell = (UITableViewCell *)[roomTable cellForRowAtIndexPath:index];
UIImageView *v = (UIImageView *)[cell.contentView viewWithTag:10];
v.image = [UIImage imageWithData:[req responseData]];
[cell release];
cell = nil;
[v release];
v = nil;
}
- (void)requestWentWrong:(ASIHTTPRequest*)req{
for (int i = 0; i < [arrImg count]; i++) {
NSMutableString *d = [[NSMutableString alloc] init];
d = [arrImg objectAtIndex:i];
//comparing the url to get correct row no of cell
if([[req.url absoluteString] isEqualToString:d]){
rowNo = i;
break;
}
}
NSLog(#"No data for cell : %d",rowNo);
NSLog(#"Request returned an error %#",[req error]);
}