I am using the Scrollviewer to load images. I get the images from Media Library and save it into local folder. If I select and add images more than 5, app get memory warning level2 app get crash.
This is code to get the Photos from database:
-(NSMutableArray*) GetPhotos:(int)folderId
{
NSString *query =[[[NSString alloc] initWithFormat:#"SELECT * FROM Photo WHERE FolderID = ?"] autorelease];
FMDatabase *db = [self.dbUtils sharedDB];
FMResultSet *rs = [db executeQuery:query, [NSNumber numberWithInt:folderId]];
NSMutableArray *results = [[NSMutableArray alloc] init];
while([rs next]) {
Photo *photo = [[Photo alloc] init];
photo.PhotoID = [rs intForColumn:#"PhotoID"];
photo.FolderID = [rs intForColumn:#"FolderID"];
photo.PhotoName = [rs stringForColumn:#"PhotoName"];
photo.UpdatedDate = [rs stringForColumn:#"UpdatedDate"];
photo.ImageData = [rs dataForColumn:#"ImageData"];
photo.Path = [rs stringForColumn:#"Path"];
photo.isPrivacy = [rs boolForColumn:#"isPrivacy"];
[results addObject:photo];
[photo release];
}
[rs close];
return results;
}
Pick the images from Image picker view controller:
#pragma mark UIImagePickerController delegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[self dismissModalViewControllerAnimated:YES];
PrivacyPixAppDelegate *appDelegate = [PrivacyPixAppDelegate appDelegate];
dispatch_queue_t image_queue;
image_queue = dispatch_queue_create("com.gordonfontenot.app", NULL);
dispatch_async(image_queue, ^{
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *pickedImage = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
NSString *fileDirectory = [FileUtils documentsDirectoryPath];
fileDirectory = [fileDirectory stringByAppendingFormat:#"/%#/",self.FolderName];
NSString *fileName = [NSString stringWithFormat:#"%#.jpg",[appDelegate newUUID]];
Photo *photo = [[Photo alloc] init];
photo.PhotoName = fileName;
photo.Path = fileDirectory;
photo.FolderID = self.FolderID;
photo.isPrivacy = FALSE;
self.btnEdit.hidden = NO;
fileDirectory = [fileDirectory stringByAppendingFormat:#"%#",fileName];
NSLog(#"FileName:%#",fileName);
NSLog(#"Directory:%#",fileDirectory);
NSData *jpegData = UIImageJPEGRepresentation(pickedImage,5.0);
[jpegData writeToFile:fileDirectory atomically:NO];
PhotoDAO *dao = [[appDelegate daos] sharedPhotoDAO];
[dao AddPhoto:photo];
[photo release];
NSMutableArray *list = [dao GetPhotos:FolderID];
self.listData = list;
[list release];
[self loadForm:self.listData];
});
});
dispatch_release(image_queue);
}
This is method for load images into scrollviewer. This method only problem to memory leak
-(void)loadForm:(NSMutableArray*)list
{
NSMutableArray *photos = [[NSMutableArray alloc] init];
if([list count] == 0)
self.btnEdit.hidden = YES;
else
self.btnEdit.hidden = NO;
for (int Count = 0; Count < [list count] ; Count ++)
{
Photo *photo = [list objectAtIndex: Count];
PhotoView *photoView = [[PhotoView alloc] initWithFrame: CGRectMake(ThumbnailSizeWidth * (Count % THUMBNAIL_COLS) + PADDING * (Count % THUMBNAIL_COLS) + PADDING,
ThumbnailSizeHeight * (Count / THUMBNAIL_COLS) + PADDING * (Count / THUMBNAIL_COLS) + PADDING + PADDING_TOP,
ThumbnailSizeWidth,
ThumbnailSizeHeight)];
[photoView setPhoto:photo];
[photoView setTag:Count];
photoView.showsTouchWhenHighlighted = YES;
photoView.userInteractionEnabled = YES;
photoView.layer.cornerRadius = 8.0;
if([FileUtils fileExistsAtPath:photo.Path fileName:photo.PhotoName])
{
UIImage *tImage= nil;
if(photo.isPrivacy)
tImage = [UIImage imageNamed:#"locked.png"];
else
{
tImage = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:#"%#%#",photo.Path,photo.PhotoName]];
MyPhoto *photo = [[MyPhoto alloc] initWithImage:tImage];
[tImage release];
[photos addObject:photo];
[photo release];
}
[photoView setImage:tImage forState:UIControlStateNormal];
[photoView addTarget:self action:#selector(FormClicked:) forControlEvents:UIControlEventTouchUpInside];
photoView.frame = CGRectMake(ThumbnailSizeWidth * (Count % THUMBNAIL_COLS) + PADDING * (Count % THUMBNAIL_COLS) + PADDING,
ThumbnailSizeHeight * (Count / THUMBNAIL_COLS) + PADDING * (Count / THUMBNAIL_COLS) + PADDING + PADDING_TOP,
ThumbnailSizeWidth,
ThumbnailSizeHeight);
[scrollViewer addSubview:photoView];
[photoView release];
}
}
if(source)
[source release];
source = [[MyPhotoSource alloc] initWithPhotos:photos];
[photos release];
CGFloat scrollableHeight = ( ThumbnailSizeHeight / THUMBNAIL_COLS) * [list count] + PADDING;
scrollViewer.contentSize = CGSizeMake(320, scrollableHeight + ( ThumbnailSizeWidth * 2) );
scrollViewer.clipsToBounds = YES;
}
Custom Button Class:
#class Photo;
#interface PhotoView : UIButton {
Photo *photo;
}
#property(nonatomic,retain) Photo *photo;
#end
Where I am not release objects properly? where is the memory leak?. This memory issue is occur when I pick image and loadimages.
memory warning is not memory leak but indicates higher memory usage. Use instrumentation to see where memory growth is happening.
Related
Hi I m creating a project where multiple Images Loading from Server With some like Count and Comment Count and a Button to like the image. I m showing the individual Images With using a Slider Controller like PageControl.
this is My code for Showing the View
-(UIView*)reloadView:(DPSliderView *)sliderView viewAtIndex:(NSUInteger)idx
{
_loading_view.hidden=TRUE;
if (idx < [photos count]) {
NSDictionary *item = [photos objectAtIndex:idx];
PhotoView *v = [[PhotoView alloc] init];
v.photoIndex = idx;
v.imageView.imageURL = [DPAPI urlForPhoto:item[#"photo_220x220"]];
NSString *placename1 = [item valueForKeyPath:#"spotting.item.name"];
NSString *firstCapChar1 = [[placename1 substringToIndex:1] capitalizedString];
NSString *cappedString1 = [placename1 stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:firstCapChar1];
v.spotNameLabel.text = cappedString1;
NSString *placename = [item valueForKeyPath:#"spotting.place.name"];
NSString *firstCapChar = [[placename substringToIndex:1] capitalizedString];
NSString *cappedString = [placename stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:firstCapChar];
NSString *place1=[NSString stringWithFormat:#"%#",cappedString];
NSString *address=[NSString stringWithFormat:#"%#",[item valueForKeyPath:#"spotting.place.address"]];
NSString *location_str3 = [NSString stringWithFormat:#"# %#, %#",place1,address];
int cap_len=[place1 length];
int address_lenth=[address length];
ZMutableAttributedString *str = [[ZMutableAttributedString alloc] initWithString:location_str3
attributes:[NSDictionary dictionaryWithObjectsAndKeys:
[[FontManager sharedManager] zFontWithName:#"Lucida Grande" pointSize:12],
ZFontAttributeName,
nil]];
[str addAttribute:ZFontAttributeName value:[[FontManager sharedManager] zFontWithName:#"Lucida Grande" pointSize:12] range:NSMakeRange(0, cap_len+3)];
[str addAttribute:ZForegroundColorAttributeName value:[UIColor colorWithRed:241/255.0f green:73.0/255.0f blue:2.0/255.0f alpha:1.0]range:NSMakeRange(0, cap_len+3)];
[str addAttribute:ZForegroundColorAttributeName value:[UIColor colorWithRed:128.0/255.0f green:121.0/255.0f blue:98.0/255.0f alpha:1.0]range:NSMakeRange(cap_len+4, address_lenth)];
v.placefontlabel.zAttributedText=str;
v.likesCountLabel.text = [NSString stringWithFormat:#"%i", [item[#"likes_count"] intValue]];
if ([_device_lang_str isEqualToString:#"es"])
{
v.shightingsLabel.text = [NSString stringWithFormat:NSLocalizedString(#"%i Vistas", nil), [item[#"sightings_count"] intValue]];
}
else
{
v.shightingsLabel.text = [NSString stringWithFormat:NSLocalizedString(#"%i Sightings", nil), [item[#"sightings_count"] intValue]];
}
if ([nolocationstr isEqualToString:#"YES"])
{
v.distanceLabel.text =[NSString stringWithFormat:#"%.2f km", [item[#"distance"] floatValue]];
}
else
{
CLLocation *location1 = [[CLLocation alloc] initWithLatitude:[[item valueForKeyPath:#"spotting.place.lat"]floatValue] longitude:[[item valueForKeyPath:#"spotting.place.lng"] floatValue]];
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:[_explore_lat_str floatValue] longitude:[_explore_lng_str floatValue]];
NSString *lat_laong=[NSString stringWithFormat:#"%f",[location1 distanceFromLocation:location2]];
int km=[lat_laong floatValue]*0.001;
NSString *distancestr=[NSString stringWithFormat:#"%d km",km];
float dist=[distancestr floatValue];
v.distanceLabel.text = [NSString stringWithFormat:#"%.2f km", dist];
}
if (![item[#"likes"] boolValue]) {
v.likeButton.enabled = YES;
v.likeButton.tag = idx;
[v.likeButton setImage:[UIImage imageNamed:#"like_new.png"] forState:UIControlStateNormal];
[v.likeButton addTarget:self action:#selector(likeAction:) forControlEvents:UIControlEventTouchUpInside];
}
else
{
v.likeButton.tag = idx;
[v.likeButton setImage:[UIImage imageNamed:#"like_new1.png"] forState:UIControlStateNormal];
}
NSArray *guides = item[#"guides"];
if ([guides count] > 0) {
NSString *guideType = [[guides objectAtIndex:0] valueForKey:#"type"];
UIImage *guidesIcon = [UIImage imageNamed:[NSString stringWithFormat:#"%#.png", guideType]];
v.guideButton.hidden = NO;
v.guideButton.tag = idx;
[v.guideButton setImage:guidesIcon forState:UIControlStateNormal];
[v.guideButton addTarget:self action:#selector(guideAction:) forControlEvents:UIControlEventTouchUpInside];
}
v.shareButton.tag = idx;
[v.shareButton addTarget:self action:#selector(shareAction:) forControlEvents:UIControlEventTouchUpInside];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(photoTapGesture:)];
[v addGestureRecognizer:tapGesture];
[tapGesture release];
return [v autorelease];
} else {
UIImageView *iv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"sc_img.png"]];
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
indicator.center = CGPointMake(CGRectGetMidX(iv.bounds), 110);
[indicator startAnimating];
[iv addSubview:indicator];
[indicator release];
return [iv autorelease];
}
}
Now My question is :
If i will Click on Like Button , Then i have to change the button image as well as like count. I can able to Change the Button Image By This Method
[sender setImage:[UIImage ImageNamed:#"image.png"]];
But How can I change the Like count of the Label ? How can i access the Particular label of the View ? I have assigned the tag But , I dont know how to assign it.I dont want to Reload Whole Slider as the Photo are loading from Network (Remote Server) . Thanks for your Time.
Just keep a reference to the label and update that.
// #interface
#property (nonatomic, strong) UILabel *myLabel;
// #implementation
_myLabel.text = #"Whatever.";
If you have multiple labels, set the tags when you create your views
newView.tag = sequenceNumber +100;
And then update
-(void)updateLabelWithTag:(NSInteger)tag {
UILabel *label = (UILabel*) [self.scrollView viewWithTag:tag];
label.text = #"Whatever.";
}
I have an application in which i am loading the images from the image caches.`
if(![[ImageCache sharedImageCache] hasImageWithKey:imagepath])
{ cell.bannerview2.image = [UIImage imageNamed:#"no_imags.png"];
NSArray *myArray = [NSArray arrayWithObjects:cell.bannerview2,imagepath,#"no_imags.png",[NSNumber numberWithBool:NO],nil];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate performSelectorInBackground:#selector(updateImageViewInBackground:) withObject:myArray];
}
else
{
cell.bannerview2.image = [[ImageCache sharedImageCache] getImagefromCacheOrUrl:imagepath];
}
}
else
{
cell.bannerview2.image = [UIImage imageNamed:#"no_imags.png"];
}
this is how i am doing the image cache process.But the problem is when the image is larger than the required frame the image orientation is changing.this is my image updating code in the appdelegate
-(void)updateImageViewInBackground:(NSArray *)idsArray{
//NSLog(#"IN METHOD idsArray %#",idsArray);
NSString *iconurl = (NSString *)[idsArray objectAtIndex:1];
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
if([[ImageCache sharedImageCache] hasImageWithKey:iconurl]){
[self performSelectorOnMainThread:#selector(updateImageViewInForeground:) withObject:idsArray waitUntilDone:NO];
[pool release];
return;
}
if([iconurl length] > 0){
[[ImageCache sharedImageCache] saveImageToCacheOfUrl:iconurl];
}
[self performSelectorOnMainThread:#selector(updateImageViewInForeground:) withObject:idsArray waitUntilDone:NO];
[pool release];
}
-(void)updateImageViewInForeground:(NSArray *)idsArray{
UIImageView *weatherView = (UIImageView *)[idsArray objectAtIndex:0];
NSString *iconurl = (NSString *)[idsArray objectAtIndex:1];
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
weatherView.image = [[ImageCache sharedImageCache] getImagefromCacheOrUrl:iconurl];
if(weatherView.image == nil){
NSString *defaultname = (NSString *)[idsArray objectAtIndex:2];
weatherView.image = [UIImage imageNamed: defaultname];
}
BOOL resizeImgView = [(NSNumber *)[idsArray objectAtIndex:3] boolValue];
if(resizeImgView){
//NSLog(#"resizeImgView %# %#",iconurl,weatherView);
weatherView.frame = CGRectMake(weatherView.frame.origin.x, weatherView.frame.origin.y, weatherView.image.size.width, weatherView.image.size.height);
}
[pool release];
}
can anybody help me?
Everytime i load images in a tableview and try to scroll the table view i get a crash in my simulator but no errors are showing. Could this be that there is to much memory being used.
Below is the code for 1 out the three views:
#import "ResultViewController.h"
#import "JobAddSiteViewController.h"
#import "SpecificAddViewController.h"
#import "JobAddSiteAppDelegate.h"
#import "JSONKit.h"
#implementation ResultViewController
#synthesize listData;
#synthesize listLocation;
#synthesize listPostDate;
#synthesize listLogo;
#synthesize listDescription;
#synthesize uiTableView;
#synthesize buttonPrev;
#synthesize buttonNext;
NSInteger *countPage = 1;
NSMutableArray *tempArray;
NSMutableArray *tempArray2;
NSMutableArray *tempArray3;
NSMutableArray *tempArray4;
NSMutableArray *tempArray5;
-(IBAction)done{
JobAddSiteViewController *second = [[JobAddSiteViewController alloc]initWithNibName:nil bundle:nil];
[self presentModalViewController:second animated:YES];
[second release];
}
-(void)loadData{
NSString *strURL2 = [NSString stringWithFormat:#"http://www.bestitjobs.co.uk/totaljobs.php", ""];
NSData *nsData2 = [NSData dataWithContentsOfURL:[NSURL URLWithString: strURL2]];
NSString *dataResult = [[NSString alloc] initWithData:nsData2 encoding:NSUTF8StringEncoding];
tempArray = [[NSMutableArray alloc] init];
tempArray2 = [[NSMutableArray alloc] init];
tempArray3 = [[NSMutableArray alloc] init];
tempArray4 = [[NSMutableArray alloc] init];
tempArray5 = [[NSMutableArray alloc] init];
NSString *strURL = [NSString stringWithFormat:#"http://www.bestitjobs.co.uk/appresults3.php?pg=%d", countPage];
NSData *nsData = [NSData dataWithContentsOfURL:[NSURL URLWithString: strURL]];
NSDictionary *listDictionary = [nsData objectFromJSONData];
NSArray* people =[listDictionary objectForKey:#"jobs"];
for (NSDictionary *person in people) {
NSString *str = [NSString stringWithFormat:#"%#", [person valueForKey:#"position"]];
NSString *str2 = [NSString stringWithFormat:#"%#", [person valueForKey:#"subcounty"]];
NSString *str3 = [NSString stringWithFormat:#"%#", [person valueForKey:#"postdate"]];
NSString *str4 = [NSString stringWithFormat:#"%#", [person valueForKey:#"logo"]];
NSString *str5 = [NSString stringWithFormat:#"%#", [person valueForKey:#"description"]];
if(![str isEqualToString:#"<null>"])
{
NSString *position = [person objectForKey:#"position"];
[tempArray addObject: position];
if(![str2 isEqualToString:#"<null>"])
{
NSString *subcounty = [person objectForKey:#"subcounty"];
[tempArray2 addObject: subcounty];
}
else{
[tempArray2 addObject: #"-"];
}
if(![str3 isEqualToString:#"<null>"])
{
NSString *postDate = [person objectForKey:#"postdate"];
[tempArray3 addObject: postDate];
}
else{
[tempArray3 addObject: #"-"];
}
if(![str4 isEqualToString:#"<null>"])
{
NSString *logo = [person objectForKey:#"logo"];
[tempArray4 addObject: [NSString stringWithFormat:#"http://www.bestitjobs.co.uk/employers/logo/Files/%#", logo]];
}
else{
[tempArray4 addObject: [NSString stringWithFormat:#"http://www.bestitjobs.co.uk/employers/logo/Files/%#", "noimage.gif"]];
}
if(![str5 isEqualToString:#"<null>"])
{
NSString *description = [person objectForKey:#"description"];
[tempArray5 addObject: description];
}
else{
[tempArray5 addObject: #"-"];
}
}
}
if (countPage == 1) {
[self.buttonPrev setEnabled:FALSE];
}
else {
[self.buttonPrev setEnabled:TRUE];
}
NSInteger val = [dataResult intValue];
NSInteger pageEnd = val/10;
if (countPage < pageEnd) {
[self.buttonNext setEnabled:TRUE];
}
else {
[self.buttonNext setEnabled:FALSE];
}
//NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:#"iPhone", #"iPod",#"iPad",nil];
self.listData = tempArray;
self.listLocation = tempArray2;
self.listPostDate = tempArray3;
self.listLogo = tempArray4;
self.listDescription = tempArray5;
[self.listData release];
[self.listLocation release];
[self.listPostDate release];
[self.listLogo release];
[self.listDescription release];
tempArray = nil;
tempArray2 = nil;
tempArray3 = nil;
tempArray4 = nil;
tempArray5 = nil;
}
- (void)viewDidLoad {
[self loadData];
[super viewDidLoad];
}
- (void)dealloc {
[tempArray dealloc];
[tempArray2 dealloc];
[tempArray3 dealloc];
[tempArray4 dealloc];
[tempArray5 dealloc];
[self.listData dealloc];
[self.listLocation dealloc];
[self.listPostDate dealloc];
[self.listLogo dealloc];
[self.listDescription dealloc];
[super dealloc];
}
#pragma mark -
#pragma mark Table View Data Source Methods
- (IBAction)prev{
countPage = countPage - 1;
[self.listData removeAllObjects];
[self.listLocation removeAllObjects];
[self.listPostDate removeAllObjects];
[self.listLogo removeAllObjects];
//NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:#"1", #"2",#"3",nil];
//self.listData = array;
[self loadData];
[self.uiTableView reloadData];
}
- (IBAction)next{
countPage = countPage + 1;
[self.listData removeAllObjects];
[self.listLocation removeAllObjects];
[self.listPostDate removeAllObjects];
[self.listLogo removeAllObjects];
//NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:#"1", #"2",#"3",nil];
//self.listData = array;
[self loadData];
[self.uiTableView reloadData];
}
- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
JobAddSiteAppDelegate *ja = (JobAddSiteAppDelegate *)[[UIApplication sharedApplication] delegate];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
for (UIView *view in cell.contentView.subviews){
if ([view isKindOfClass:[UILabel class]]){
UILabel *label = (UILabel *)view;
if (label.tag == 1) {
ja.jobText = label.text;
}
if (label.tag == 2) {
ja.locationText = label.text;
}
if (label.tag == 3) {
ja.dateText = label.text;
}
if (label.tag == 4) {
}
if (label.tag == 5) {
ja.specificText = label.text;
}
}
if ([view isKindOfClass:[UIImageView class]]){
UIImageView *image = (UIImageView *)view;
if (image.tag = 4){
ja.logoText = image.image;
}
}
}
SpecificAddViewController *second = [[SpecificAddViewController alloc]initWithNibName:nil bundle:nil];
[self presentModalViewController:second animated:YES];
[second release];
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return [self.listData count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath
*)indexPath
{
if (indexPath.section == 1 && indexPath.row == 1) {
return 65;
}
return 65;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
UILabel *labelMain;
UILabel *labelLocation;
UILabel *labelDate;
UIImageView *image;
UILabel *ref;
if (cell == nil) {
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier] autorelease];
image = [[[UIImageView alloc] initWithFrame:CGRectMake(0,3,80,62)] autorelease];
image.tag = 4;
[cell.contentView addSubview:image];
labelMain = [[[UILabel alloc] initWithFrame:CGRectMake(90,3,200,20)] autorelease];
labelMain.tag = 1;
labelMain.font = [UIFont systemFontOfSize:14.0];
[cell.contentView addSubview:labelMain];
labelLocation = [[[UILabel alloc] initWithFrame:CGRectMake(90,20,200,20)] autorelease];
labelLocation.tag = 2;
labelLocation.font = [UIFont systemFontOfSize:12.0];
labelLocation.textColor = [UIColor darkGrayColor];
[cell.contentView addSubview:labelLocation];
labelDate = [[[UILabel alloc] initWithFrame:CGRectMake(90,40,200,20)] autorelease];
labelDate.tag = 3;
labelDate.font = [UIFont systemFontOfSize:12.0];
labelDate.textColor = [UIColor darkGrayColor];
[cell.contentView addSubview:labelDate];
ref = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 0)] autorelease];
ref.tag = 5;
[cell.contentView addSubview:ref];
}
[(UILabel *)[cell.contentView viewWithTag:1] setText:[self.listData objectAtIndex:indexPath.row]];
[(UILabel *)[cell.contentView viewWithTag:2] setText:[self.listLocation objectAtIndex:indexPath.row]];
[(UILabel *)[cell.contentView viewWithTag:3] setText:[self.listPostDate objectAtIndex:indexPath.row]];
[(UILabel *)[cell.contentView viewWithTag:5] setText:[self.listDescription objectAtIndex:indexPath.row]];
NSString *imagePath = [self.listLogo objectAtIndex:indexPath.row];
image.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imagePath]]];
return cell;
}
#end
The call
image.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imagePath]]];
will block the execution thread and being indeterminately long in terms of network use this is a bad thing. Each of your cells needs to wait to the image to load.
Check out "lazy loading of tableView cells" as a research topic.
Instead you should give the URL to the cell and tell it to load the image off the main thread.
as in
[cell loadImageAtURL:someURL];
and within a UITableViewCell subclass implementation
-(void)loadImageAtURL:(NSURL *)aurl
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSData *data = [NSData dataWithContentsOfURL:aurl];
if (data) {
UIImage *image = [UIImage imageWithData:data];
//must update UI on main queue
dispatch_async(dispatch_get_main_queue() ,^{
self.cellImageView = image;
}
}
});
}
Theres also a ton of Obj-C image loaders . EGOCache is my go to library but have a look round.
In summary the cell needs to own the image load process not the tableview because theres no guarantee that the cell will not be reused before the image loads and displays.
NSInteger is a primitive type, which means it can be stored locally on the stack. You don't need to use a pointer to access it. The way you are using it i think is a problem, getting the pointer value instead of the actual value of the primitive type.
I think this is what you want for the declaration/initialization of countPage:
NSInteger countPage = 1;
I have a multiple file to attach inside the picker view. When user select that picker view item, they can click email button to attach the chosen file. How do I do so in my picker view?
Here is my sample code.
M File :
-(void)pickerViewEmail:(UIPickerView *)pickerViewEmail didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if ([[musicList objectAtIndex:row] isEqual:#"m1"])
{
MFMailComposeViewController *pickerEmail = [[MFMailComposeViewController alloc] init];
pickerEmail.mailComposeDelegate = self;
NSString *path = [[NSBundle mainBundle] pathForResource:#"m1" ofType:#"mp3"];
NSData *myData = [NSData dataWithContentsOfFile:path];
[pickerEmail addAttachmentData:myData mimeType:#"audio/mp3" fileName:#"m1"];
[pickerEmail setSubject:#"Hello!"];
// Set up recipients
NSArray *toRecipients = [NSArray arrayWithObject:#"first#example.com"];
NSArray *ccRecipients = [NSArray arrayWithObjects:#"second#example.com", #"third#example.com", nil];
NSArray *bccRecipients = [NSArray arrayWithObject:#"fourth#example.com"];
[pickerEmail setToRecipients:toRecipients];
[pickerEmail setCcRecipients:ccRecipients];
[pickerEmail setBccRecipients:bccRecipients];
// Fill out the email body text
NSString *emailBody = #"Hello";
[pickerEmail setMessageBody:emailBody isHTML:NO];
[self presentModalViewController:pickerEmail animated:YES];
[pickerEmail release];
}
Email Button: How do i start from here.
-(IBAction)showEmail
{
if ([MFMailComposeViewController canSendMail])
{
[self pickerEmail]; I have a yellow error when i call this. What is the right solution?
}
else
{
}
}
When user selects rows in your pickerviews, you save row titles to some common variables
using
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
You can use one pickerView delegate method for all your pickerViews. To determine, which pickerView is selected you should retrieve sender.
Then in your showEmail method you just use that saved variables.
Sample code. Just bind 3 different delegates to 3 sliders in IB:
-(IBAction)slider1Changed:(id)sender {
UISlider *slider = (UISlider *) sender;
int progressAsInt =(int)(slider.value + 0.5f);
NSString *newText =[[NSString alloc]
initWithFormat:#"%d",progressAsInt];
label1.text = newText;
NSString *imgFileName = [NSString stringWithFormat:#"gold%i.png", progressAsInt];
image1.image = [UIImage imageNamed:imgFileName];
[newText release];
}
-(IBAction)slider2Changed:(id)sender {
UISlider *slider = (UISlider *) sender;
int progressAsInt =(int)(slider.value + 0.5f);
NSString *newText =[[NSString alloc]
initWithFormat:#"%d",progressAsInt];
label2.text = newText;
NSString *imgFileName = [NSString stringWithFormat:#"gold%i.png", progressAsInt];
image2.image = [UIImage imageNamed:imgFileName];
[newText release];
}
-(IBAction)slider3Changed:(id)sender {
UISlider *slider = (UISlider *) sender;
int progressAsInt =(int)(slider.value + 0.5f);
NSString *newText =[[NSString alloc]
initWithFormat:#"%d",progressAsInt];
label3.text = newText;
NSString *imgFileName = [NSString stringWithFormat:#"gold%i.png", progressAsInt];
image3.image = [UIImage imageNamed:imgFileName];
[newText release];
}
i am parsing a json object and storing the song objects in songs, a nsmutable array.
while am displaying the image of the song i.e. while accessing the object from the array its giving all values nil in that object.
in the following code in setSongsScrollView method, in for loop while accessing the song object from songs array its showing nill in the debugger and crashing with error EXEBadacess.But the count of that array is giving correct.
can any body help me out please
- (void)viewWillAppear:(BOOL)animated{
[super viewDidLoad];
[self parsingTheStation];
[self load_images];
[self setSongsScrollView];
}
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
- (void)parsingTheStation{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http:...."]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *jsonString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF32BigEndianStringEncoding];
NSDictionary *dictionary = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:nil];
songs =[[NSMutableArray alloc]init];
NSArray *songObjects = [dictionary objectForKey:#"songs"];
for(NSDictionary *s in songObjects){
aSong = [[Song alloc] init];
aSong.artist = [s objectForKey:#"by"];
aSong.genre = [s objectForKey:#"genre"];
aSong.cover = [s objectForKey:#"cover"];
aSong.song_id = [s objectForKey:#"id"];
aSong.rank = [s objectForKey:#"rank"];
aSong.title = [s objectForKey:#"title"];
aSong.link = [s objectForKey:#"link"];
[songs addObject:aSong];
[aSong release];
}
NSLog(#"total number of songs is : %d",[songs count]);
}
-(void)setSongsScrollView {
songsContainer = [[UIScrollView alloc]init];
int songsCount = [self.songs count];
//totla no. of songs we get +4
int tSongs = songsCount+4;
int n = sqrt(tSongs);
int p = n,q = n;
int remSongs = tSongs-(n*n);
if(remSongs >= n){
q = q+(remSongs/n);
if((remSongs%n)>0)
q++;
}else q++;
for(int i=0;q>p;i++){
q--;
p++;
}
NSLog(#"total songs..%d",tSongs);
NSLog(#"total rows..%d",q);
NSLog(#"total columns..%d",p);
songsContainer.contentSize = CGSizeMake(120*q, 120*p);
int x =0, y=240, col=1;
for(int i=0;i<songsCount;i++){
CGRect imgFrame = CGRectMake(x, y, 118, 118);
NSLog(#"songs conunt ...%d",[songs count]);
Song *thesong = [[Song alloc]init];
thesong = [self.songs objectAtIndex:i];
NSString *filename = [NSString stringWithFormat:#"%#/%#", [LazyImageView dataPath], [thesong.cover lastPathComponent]];
UIImageView *tempImg = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:filename]];
tempImg.tag = i;
tempImg.frame = imgFrame;
[songsContainer addSubview:tempImg];
[tempImg release];
[thesong release];
y += 120;
if(y>=(120*p)){
NSLog(#"total y..%d",y);
col++;
x += 120;
if(col>=3)
y=0;
else
y=240;
}
}
NSLog(#"total y..%d",y);
NSLog(#"content size..%d,%d",120*q,120*p);
}
-(void)load_images{
for(int i=0;i<[songs count];i++){
Song *rsong = [[Song alloc]init];
rsong = [self.songs objectAtIndex:i];
lazyBigImg = [[LazyImageView alloc] init];
NSURL* url = [NSURL URLWithString:rsong.cover];
[lazyBigImg loadImageFromURL:url];
[lazyBigImg release];
[rsong release];
}
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[songs release];
[lazyBigImg release];
[onAirBtn release];
[chartsBtn release];
[dealsBtn release];
[searchBtn release];
[stNameLbl release];
[aSong release];
[songsContainer release];
[super dealloc];
}
#end
Marcel has basically got the right answer but I think a little more explanation is needed. Look at the following lines from setSongsScrollView:
Song *thesong = [[Song alloc]init];
The above line allocates a new Song that you own and assigns a reference to it to thesong
thesong = [self.songs objectAtIndex:i];
The above line replaces that reference with a new reference to a song from the array that you don't own. Remember that: you do not own the song referenced by thesong now. There are now no more references left to the object you just allocated, but you still own it. The object has therefore leaked.
NSString *filename = [NSString stringWithFormat:#"%#/%#", [LazyImageView dataPath], [thesong.cover lastPathComponent]];
Use stringByAppendingPathComponent: to build file paths, not stringWithFormat:.
UIImageView *tempImg = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:filename]];
tempImg.tag = i;
tempImg.frame = imgFrame;
[songsContainer addSubview:tempImg];
[tempImg release];
[thesong release];
The last line in the above sequence releases the object referenced by thesong. As noted above, you do not own that object. You must not release it, but you have anyway. This means that, at some point, may be now, maybe later, the object will be deallocated while something (probably the array) still thinks it has a valid reference. That's what causes the crash.
-(void)load_images{
for(int i=0;i<[songs count];i++){
Song *rsong = [[Song alloc]init];
rsong = [self.songs objectAtIndex:i];
lazyBigImg = [[LazyImageView alloc] init];
NSURL* url = [NSURL URLWithString:rsong.cover];
[lazyBigImg loadImageFromURL:url];
[lazyBigImg release];
[rsong release];
}
}
The above method contains exactly the same error.
You're creating a new Song instance (thesong), then assign this very instance to a song presumably already in the array. That makes no sense at all and is probably responsible for the memory error.
You shouldn't need to be creating new Songs if they are already in the array. Instead:
Song *thesong = [self.songs objectAtIndex:i];
Also look into using the Objective-C 2.0 for-each loop syntax.