I am recently having a memory crash and I am suspecting that I am failing to empty the array, This is my code for the array
- (void)viewDidLoad
{
allImagesArray = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *location=#"Bottoms";
NSString *fPath = [documentsDirectory stringByAppendingPathComponent:location];
NSArray *directoryContent = [[NSFileManager defaultManager] directoryContentsAtPath: fPath];
collectionBottoms.delegate =self;
collectionBottoms.dataSource=self;
for(NSString *str in directoryContent){
NSLog(#"i");
NSString *finalFilePath = [fPath stringByAppendingPathComponent:str];
NSData *data = [NSData dataWithContentsOfFile:finalFilePath];
if(data)
{
UIImage *image = [UIImage imageWithData:data];
[allImagesArray addObject:image];
NSLog(#"array:%#",[allImagesArray description]);
}}
}
Ho can I free the memory by releasing the object in the array?
You save the image array in Plist. After save you just re initialize your array it will clear the memory in array. Then are you using ARC or not? Because ARC is more comfortable for this. Then re-initialze or removeAllObject from array in -viewWillDisappear
Hi Just release the memory once object works is over. Here is the code for you.
- (void)viewDidLoad
{
allImagesArray = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *location=#"Bottoms";
NSString *fPath = [documentsDirectory stringByAppendingPathComponent:location];
NSArray *directoryContent = [[NSFileManager defaultManager] directoryContentsAtPath: fPath];
collectionBottoms.delegate =self;
collectionBottoms.dataSource=self;
for(NSString *str in directoryContent)
{
NSString *finalFilePath = [fPath stringByAppendingPathComponent:str];
NSData *data = [NSData dataWithContentsOfFile:finalFilePath];
if(data)
{
UIImage *image = [UIImage imageWithData:data];
[allImagesArray addObject:image];
NSLog(#"array:%#",[allImagesArray description]);
image = nil;
}
finalFilePath=nil;
data=nil;
}
paths= nil;
documentsDirectory= nil;
location= nil;
fPath= nil;
directoryContent = nil;
}
If you are using this image array, allImagesArray, when the view is visible then put this code in viewWillAppear or viewDidAppear methods of UIViewController.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
allImagesArray = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *location=#"Bottoms";
NSString *fPath = [documentsDirectory stringByAppendingPathComponent:location];
NSArray *directoryContent = [[NSFileManager defaultManager] directoryContentsAtPath: fPath];
collectionBottoms.delegate =self;
collectionBottoms.dataSource=self;
for(NSString *str in directoryContent){
NSLog(#"i");
NSString *finalFilePath = [fPath stringByAppendingPathComponent:str];
NSData *data = [NSData dataWithContentsOfFile:finalFilePath];
if(data)
{
UIImage *image = [UIImage imageWithData:data];
[allImagesArray addObject:image];
NSLog(#"array:%#",[allImagesArray description]);
}
}
}
And, then release it in viewWillDisappear/viewDidDisappear methods of UIViewController.
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[allImagesArray removeAllObjects];
//[allImagesArray release]; // (Uncomment) Call this only if you are not using ARC.
}
Alternatively, a quick, dirty but safe fix is (without knowing your usage of allImagesArray) -
- (void)viewDidLoad
{
[super viewDidLoad];
// Remove previously added objects.
if (allImagesArray != nil && allImagesArray.count > 0) {
[allImagesArray removeAllObjects];
}
// Allocate memory if not done earlier (i.e. first time).
if (allImagesArray == nil) {
allImagesArray = [[NSMutableArray alloc] init];
}
// Rest of your code as stated in your question
}
Related
NSString *path = [NSString stringWithFormat:#"%#/%#",[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) objectAtIndex:0], parentFolderName] ;
NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
NSEnumerator *enumerator = [dirContents objectEnumerator] ;
id fileName ;
NSMutableArray *fileArray = [[NSMutableArray alloc] init] ;
while (fileName = [enumerator nextObject])
{
NSString *fullFilePath = [path stringByAppendingPathComponent:fileName];
NSRange textRangeJpg = [[fileName lowercaseString] rangeOfString:[#".png" lowercaseString]];
if (textRangeJpg.location != NSNotFound)
{
originalImage = [UIImage imageWithContentsOfFile:fullFilePath];
[fileArray addObject:originalImage];
}
}
You should try this code to save and retrieve image from the document directory:
I have implemented these methods in AppDelegate.m
-(NSString *)getDocumentDirectoryPath:(NSString *)Name
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:Name];
NSLog(#"savedImagePath: %#", savedImagePath);
return savedImagePath;
}
-(BOOL)saveImage:(UIImage *)image withName:(NSString *)Name
{
NSData *imageData = UIImagePNGRepresentation(image);
BOOL success = [imageData writeToFile:[AppDelegate getDocumentDirectoryPath:Name] atomically:NO];
return success;
}
-(UIImage *)getRealtorImage:(NSString *)Name
{
UIImage *img = [UIImage imageWithContentsOfFile:[AppDelegate getDocumentDirectoryPath:Name]];
return img;
}
#Sandy Please try the following code
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100,100,200,200)];
NSData *imgData = [[NSData alloc] initWithContentsOfURL:[NSURL fileURLWithPath:imageFilePath]];
if (imgData != nil)
{
UIImage *thumbNail = [[UIImage alloc] initWithData:imgData];
imageView.image = thumbNail;
}
[self.view addSubView:imageView];
I am trying to fetch Images which i am storing in directory which i have shown in below code . I have tried a lot in StachOverFlow And Chats but not able to achieve the task . Actually i want to generate array of images from the array of filePath which are storing the path of images . Which i will show in UICollectionView . Please check my code and tell me what all can be done to achieve the needed . Thanks in advance
I have array of filepath already generated , i just want to fetch images from them and show it in grid view
-(void)plistRender{
// get paths from root direcory
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
// get documents path
NSString *documentsPath = [paths objectAtIndex:0];
// get the path to our Data/plist file
NSString *plistPath = [documentsPath stringByAppendingPathComponent:#"PhotoBucket.plist"];
//pngDATA.....
NSString *totalName = [NSString stringWithFormat:#"EGK_%# ", [NSDate date]];
PhotodocumentsPath = [paths objectAtIndex:0];
PhotofilePath = [PhotodocumentsPath stringByAppendingPathComponent:totalName]; //Add the file name
NSData *pngData = UIImagePNGRepresentation(printingImage);
//Write image to the file directory .............
[pngData writeToFile:[self documentsPathForFileName:PhotofilePath] atomically:YES];
[photos_URL addObject:PhotofilePath];
[photos addObject:totalName];
[grid_copy addObject:[NSNumber numberWithInteger:count]];
[grids addObject:whichProduct];
[Totalamount addObject:[NSNumber numberWithInteger:amt]];
NSDictionary *plistDictionary = [NSDictionary dictionaryWithObjects: [NSArray arrayWithObjects: photos,grids,grid_copy,Totalamount,nil] forKeys:[NSArray arrayWithObjects: #"Photo_URL",#"Product",#"Copy",#"Amount", nil]];
NSString *error = nil;
// create NSData from dictionary
NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:plistDictionary format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];
// check is plistData exists
if(plistData)
{
// write plistData to our Data.plist file
[plistData writeToFile:plistPath atomically:YES];
}
else
{
NSLog(#"Error in saveData: %#", error);
}
NSString *string = [[NSString alloc] initWithData:plistData encoding:NSUTF8StringEncoding];
NSLog(#" plist Data %#", string);
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"PhotoBucket"]){
RecipeCollectionViewController *photoBucket = [segue destinationViewController];
NSLog(#"Prepare Segue%#",photoBucket.photoCollection);
NSLog(#"Number of photos %#",photos_URL);
NSMutableArray *imgQueue = [[NSMutableArray alloc] initWithCapacity:photos_URL.count];
for (NSString* path in photos_URL) {
[imgQueue addObject:[UIImage imageWithContentsOfFile:path]];
}
photoBucket.photoCollection = imgQueue;
}
}
try this
for(int i=0;i<[filePathsArray count];i++)
{
NSString *strFilePath = [filePathsArray objectAtIndex:i];
if ([[strFilePath pathExtension] isEqualToString:#"jpg"] || [[strFilePath pathExtension] isEqualToString:#"png"] || [[strFilePath pathExtension] isEqualToString:#"PNG"])
{
NSString *imagePath = [[stringPath stringByAppendingFormat:#"/"] stringByAppendingFormat:strFilePath];
NSData *data = [NSData dataWithContentsOfFile:imagePath];
if(data)
{
UIImage *image = [UIImage imageWithData:data];
}
}
}
Hi you can fetch like this:
NSArray *pathPlist1 =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryStr1 = [pathPlist1 objectAtIndex:0];
NSString *plistLocation1 =
[documentsDirectoryStr1 stringByAppendingPathComponent:#"ImageStorage"];
NSFileManager *filemgr;
NSArray *filelist;
int i;
filemgr =[NSFileManager defaultManager];
filelist = [filemgr contentsOfDirectoryAtPath:plistLocation1 error:NULL];
NSLog(#"filelist =%lu",[filelist count]);
cacheImagesArray=[[NSMutableArray alloc] init];
cacheImagesDataArray=[[NSMutableArray alloc] init];
for (i = 0; i < [filelist count]; i++){
NSLog(#"%#", [filelist objectAtIndex: i]);
NSString *imageName=[NSString stringWithFormat:#"%#",[filelist objectAtIndex: i]];
NSString *path=[NSString stringWithFormat:#"%#/%#",plistLocation1, [filelist objectAtIndex: i]];
NSLog(#"Path is =%#",path);
NSData* data = [NSData dataWithContentsOfFile:path];
[cacheImagesDataArray addObject:data];
[cacheImagesArray addObject:imageName];
}
thanks
Usually when you have the images in the project file you use the code
arraycollectionimages = [[NSArray alloc]]initwithobjects
however I want to show the images that are saved in the directories. I have created multiple directories so I just want to recall image for one of them. To make this work I want to use this code however I cannot do this? I just stuck it it in as follows but did not work well.
- (void)viewDidLoad {
NSArray *arrayCollectionImages = [[NSArray alloc ]init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *location=#"Genre1";
NSString *fPath = [documentsDirectory stringByAppendingPathComponent:location];
NSArray *directoryContent = [[NSFileManager defaultManager] directoryContentsAtPath: fPath];
for(NSString *str in directoryContent){
NSString *finalFilePath = [fPath stringByAppendingPathComponent:str];
NSData *data = [NSData dataWithContentsOfFile:finalFilePath];
if(data)
{
UIImage *image = [UIImage imageWithData:data];
[arrayCollectionImages addObject:image];
}
}
I think your directory search is probably taking long. Try this...
- (void)viewDidLoad {
dispatch_queue_t searchQ = dispatch_queue_create("com.awesome", 0);
dispatch_async(searchQ, ^{
NSArray *arrayCollectionImages = [[NSArray alloc ]init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *location=#"Genre1";
NSString *fPath = [documentsDirectory stringByAppendingPathComponent:location];
NSArray *directoryContent = [[NSFileManager defaultManager] directoryContentsAtPath: fPath];
for(NSString *str in directoryContent){
NSString *finalFilePath = [fPath stringByAppendingPathComponent:str];
NSData *data = [NSData dataWithContentsOfFile:finalFilePath];
if(data)
{ dispatch_async(dispatch_get_main_queue(),^{
UIImage *image = [UIImage imageWithData:data];
});
[arrayCollectionImages addObject:image];
}
}
});
}
The code basically spawns off another thread on the search and puts the image when its ready.
I do not know how to declare your directory in the .h file. In my View Controller I have written
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSArray *allImagesArray = [[NSArray alloc ]init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *location=#"Hats";
NSString *fPath = [documentsDirectory stringByAppendingPathComponent:location];
NSArray *directoryContent = [[NSFileManager defaultManager] directoryContentsAtPath: fPath];
for(NSString *str in directoryContent){
NSString *finalFilePath = [fPath stringByAppendingPathComponent:str];
NSData *data = [NSData dataWithContentsOfFile:finalFilePath];
if(data)
{
UIImage *image = [UIImage imageWithData:data];
[allImagesArray addObject:image];
}}}
however of course I get an error saying no visible at interface for"NSMutableArray" declares the selector "addObject".I do not know how to declare my directory called Hats in the .h file. I think you use NSMutableArray or something but I don't know for sure..
You want to use an NSMutableArray instead of an NSArray. You can't alter an NSArray after creation.
NSMutableArray *allImagesArray = [[NSMutableArray alloc ]init];
And then you can do
[allImagesArray addObject:image];
NSArray needs to be populated when it is initialized. So if you want to add some object to an array then you have to use an NSMutableArray.
I have a CSV file that I'm downloading from an S3 account and I would like to show it in my ios app by using the Quicklook framework.
The error I'm getting is in my console. It says
QLPreviewController's datasource shouldn't be nil at this point.
This appears after this line of code runs // Set data source
[previewer setDataSource:self];
here's all the code for downloading the file, saving it and then loading with quicklook
-(void)showDocument
{
NSString *stringURL = #"http://jornada.s3.amazonaws.com/Dust.csv";
NSURL *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url options:NSDataReadingUncached error:nil];
if ( urlData )
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,#"tempfile.csv"];
//[urlData writeToFile:filePath atomically:YES];
BOOL newFile = [[NSFileManager defaultManager] createFileAtPath:filePath contents:urlData attributes:nil];
arrayOfDocuments = [[NSArray alloc] initWithObjects:
filePath, nil];
QLPreviewController *previewer = [[QLPreviewController alloc] init];
[self addSubview:previewer.view];
// Set data source
[previewer setDataSource:self];
// Which item to preview
[previewer setCurrentPreviewItemIndex:0];
}
}
/*---------------------------------------------------------------------------
*
*--------------------------------------------------------------------------*/
- (NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController *) controller
{
return [arrayOfDocuments count];
}
/*---------------------------------------------------------------------------
*
*--------------------------------------------------------------------------*/
- (id <QLPreviewItem>)previewController: (QLPreviewController *)controller previewItemAtIndex:(NSInteger)index
{
// Break the path into it's components (filename and extension)
NSArray *fileComponents = [[arrayOfDocuments objectAtIndex: index] componentsSeparatedByString:#"."];
NSArray *filePaths = [[fileComponents objectAtIndex:0] componentsSeparatedByString:#"/"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:[((NSString *)[filePaths objectAtIndex:[filePaths count]-1]) stringByAppendingString:(NSString*)[fileComponents objectAtIndex:1]]];
// Use the filename (index 0) and the extension (index 1) to get path
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
if (fileExists) {
//
}
return [NSURL fileURLWithPath:filePath isDirectory:NO];
}
You don't add a preview controller's view to your view - you present the preview controller. And you should do that after setting the data source! So, in this order:
QLPreviewController* preview = [QLPreviewController new];
preview.dataSource = self;
[self presentViewController:preview animated:YES completion:nil];