Crash when using URL for swapping images - iphone

#implementation SlideShowViewController
- (id)init
{
NSString *temp = [NSString alloc];
[temp stringwithString:#"http://www.inetwallpaper.com/homescreenhero/sunsets/wall009.jpg"];
temp=[(NSString *)CFURLCreateStringByAddingPercentEscapes(
nil,
(CFStringRef)temp,
NULL,
NULL,
kCFStringEncodingUTF8)
autorelease];
NSData *dato = [NSData alloc];
dato=[NSData dataWithContentsOfURL:[NSURL URLWithString:temp]];
if (self = [super initWithNibName:nil bundle:nil])
{
NSArray * images = [NSArray arrayWithObjects:[UIImage imageWithData:dato],[UIImage imageWithData:dato], [UIImage imageWithData:dato], [UIImage imageWithData:dato], [UIImage imageWithData:dato], nil];
self.view = [[[SlideShowView alloc] initWithImages:images] autorelease];
}
return self;
}
I used the following code to load images from the server and view it as that of a photo album
But when the code is run it gets crashed
the error message in console is as follows
2011-06-24 23:54:01.837
SlideShow[13654:207] *
-[NSPlaceholderString stringwithString:]: unrecognized
selector sent to instance 0x49117e0
2011-06-24 23:54:01.839
SlideShow[13654:207] Terminating
app due to uncaught exception
'NSInvalidArgumentException', reason:
'** -[NSPlaceholderString
stringwithString:]: unrecognized
selector sent to instance 0x49117e0'
2011-06-24 23:54:01.840
SlideShow[13654:207] Stack: (
42178640,
43336492,
42187355,
41649782,
41646578,
12567,
7791,
2906510,
2910543,
2936126,
2917623,
2949592,
51171708,
41457820,
41453736,
2908705 ) terminate called after throwing an instance of 'NSException'
it works if the URLS are replaced by the images
could any one help me
I'm a beginner so its hard for me to find it out
thanks

You are trying to call an NSString class method with an instance (an incorrectly created instance at that) here
NSString *temp = [NSString alloc];
[temp stringwithString:#"http://www.inetwallpaper.com/homescreenhero/sunsets/wall009.jpg"];
Change to
NSString *temp = #"http://www.inetwallpaper.com/homescreenhero/sunsets/wall009.jpg";
EDIT:
You are doing several things wrong like calling alloc on things and then setting them to something else. (*temp and *data) when you alloc something it should always be followed with a call to init or initXXXX. Next you do not even need those alloc calls because you are setting the pointer to something else on the line right beneath it which causes a memory leak.
This is all you need
NSData *dato = [NSData dataWithContentsOfURL:[NSURL URLWithString:temp]];
Then you are creating a bunch of images with the same data object. You are also blocking the calling thread while you are downloading the image which should done later probably around time of viewDidLoad asynchronously.
The init function of the view controller is not the place for setting the view. Implement loadView and the system will call it when it is needed to minimize the applications memory footprint.

Related

viewDidLoad using Persistence

I have problem with my Iphone project in viewDidLoad event the app crash on
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
I am trying to store information from text Filed can someone help me to solve the problem
- (void)viewDidLoad{
NSString *filePath = [self dataFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSArray *array = [[NSArray alloc] initWithContentsOfFile:filePath];
for (int i = 0; i < 2; i++) {
UITextField *theField = self.lineFields[i];
theField.text = array[i];
}
NSData *data = [[NSMutableData alloc]
initWithContentsOfFile:filePath];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]
initForReadingWithData:data];
BIDThreeLines *threelines = [unarchiver decodeObjectForKey:kRootKey];
[unarchiver finishDecoding];
for (int i = 0; i < 2; i++) {
UITextField *theField = self.lineFields[i];
theField.text = threelines.lines[i];
}
}
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(applicationWillResignActive:)
name:UIApplicationWillResignActiveNotification
object:app];
}
Error
2013-03-25 23:29:45.592 MobilePaymentsApp[1182:c07] -[__NSCFArray objectForKey:]: unrecognized selector sent to instance 0x8d0e8d0
2013-03-25 23:29:45.593 MobilePaymentsApp[1182:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFArray objectForKey:]: unrecognized selector sent to instance 0x8d0e8d0'
*** First throw call stack:
(0x1c96012 0x10d3e7e 0x1d214bd 0x1c85bbc 0x1c8594e 0x1c0ae18 0xb030e8 0x339c 0xf91c7 0xf9232 0x483d5 0x4876f 0x48905 0x51917 0x2cc5 0x15157 0x15747 0x1694b 0x27cb5 0x28beb 0x1a698 0x1bf1df9 0x1bf1ad0 0x1c0bbf5 0x1c0b962 0x1c3cbb6 0x1c3bf44 0x1c3be1b 0x1617a 0x17ffc 0x29fd 0x2925)
libc++abi.dylib: terminate called throwing an exception
(lldb)
https://github.com/a-elnajjar/MobilePaymentsApp
NSKeyedArchiver returns object that you have stored in it. eg. if you have stored an array then it will return an array. so be careful while unarchiveing objects.
in following example i have read an array from NSKeyedUnarchiver.
NSData *data = [[NSMutableData alloc] initWithContentsOfFile:filePath];
NSArray *arr = [NSKeyedUnarchiver unarchiveObjectWithData:data];
Look in the crash log's stack trace to see where exactly this call is
happening.
If the variable you're sending -row to isn't actually typed as an
NSArray, it's likely that you've failed to follow the memory
management rules for that variable. These same symptoms are very
commonly caused by that. Something that responds to -row could have
existed at one point, been deallocated because you didn't -retain it,
and then an NSArray was later allocated in that spot.
Run a "Build & Analyze," and re-re-review the memory management
guidelines until you know them in your sleep.
Source: [NSCFArray row]: unrecognized selector sent to instance 0x3953a20

Memory leak when using NSString inside for loop

I have 100 images in my resource bundle named like image1.jpg,image2.jpg.
Basically what i am trying to do is create path names to those images dynamically inside a for loop.
While testing in simulator,the images loaded fine and the app did not crash.But while testing the app with instruments i was shocked to see the heavy memory leak that was happening while i was creating the path1 object.
I am pasting the entire method here for reference
- (id)init {
self = [super init];
if (self) {
self.arrayImages = [[[NSMutableArray alloc] init] autorelease];
for(int i=1 ; i<100 ; i++){
NSString *str = [NSString stringWithFormat:#"Century%d",i];
NSString *path1 = [[NSBundle mainBundle] pathForResource:str ofType:#"jpg"];
[self.arrayImages addObject:path1];
}
}
return self;
}
As i have not made use of any alloc inside the loop i dont have any ownership and hence no right to release the object.What is the reason for this memory leak??
Kindly explain the problem and provide the necessary solution in order to fix it..
As always,any help is highly appreciated..
arrayImages is retaining path1, and so if you do not release arrayImages it will leak. How are you creating arrayImages, and are you releasing it anywhere?
Edited based on comments:
Make sure you release arrayImages in your -dealloc method like so: [arrayImages release]; (note the lack of self).
There is no leak in the code you've shown.
There are (at least) two possibilities:
You have a leak in code you didn't paste into your question
Everything is fine and Instruments gave you a false-positive
Your loop will create a lot of autoreleased variables. These won't be deallocated until after the loop has finished, but that's how it's supposed to work.
The reason for the leak would be this line right here:
NSString *str = [NSString stringWithFormat:#"Century%d",i];
By using convenience methods in Objective-C, what happens in the background is the following:
NSString *str = [[[NSString alloc] initWithFormat:#"Century%d", i] autorelease];
Not using alloc/init to create a weak reference is a misconception. You are always the owner of a created object, no matter how you create it. The convenience method simply does the alloc/init and autoreleases it for you.
Here's what I would suggest you do to avoid leaking memory:
- (id)init {
self = [super init];
if (self) {
self.arrayImages = [[[NSMutableArray alloc] init] autorelease];
NSAutoreleasePool *tmpPool = [[NSAutoreleasePool alloc] init];
for(int i = 1 ; i < 100 ; i++) {
NSString *str = [NSString stringWithFormat:#"Century%d",i];
NSString *path1 = [[NSString alloc] initWithString:[[NSBundle mainBundle] pathForResource:str ofType:#"jpg"]];
[self.arrayImages addObject:path1];
[path1 release];
}
[tmpPool drain];
}
return self;
}
Let me know if this works better for you.
-EDIT- Allocating the path1 object and releasing it after adding to arrayImages.

Table View Scrolling cause problems when I use dynamic data

When I use static data there is no problem but I use dynamic data with Web services there is problem (table view scrolling cause crash program) why? If I comment these lines add static data it works;
//tempCs is NSDictionary
tempDc = [arrHaberler objectAtIndex:indexPath.row];
cell.textLabel.text = [tempDc valueForKey:#"short_header"];
NSData *imgData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:[tempDc valueForKey:#"iphone_src"]]];
UIImage *myImage = [[[UIImage alloc] initWithData:imgData] autorelease];
cell.imageView.image = myImage;
You don't release the imgData. You'd want to do that after creating the UIImage.
Other than that, from your description, maybe the numbersOfRowsInSection method has an error?
EDIT (after discussion):
(crash due to unrecognized selector (ie method from NSArray) sent to instance of NSString)
There are many ways you can come to this state, including accessing some memory that was released and reused (ie missing a retain), or overwriting an array with a string due to some parsing yielding a wrong result.
I try something with made an comment another lines and problem is on this line:
tempDc = [arrHaberler objectAtIndex:indexPath.row];
I change "indexPath.row" to "0" still cause crash... Problem about when is assign data to NSDictionary
There is no null-checking (setting NSData *imgData and setting UIImage *myImage) and there in a synchronous call to server. fmpov, problem is out there.
#VNevzatR i am just asking you that Are you are calling plenty no of images from somewhere....because this is no the problem you UITableView as you said working fine in static data,the problem is some where else, so if you are calling plenty of images at a time....Try doing this way...release that pool.
-(void) parseImages
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//Fetch your images here
[self performSelectorOnMainThread:#selector(Done) withObject:nil waitUntilDone:YES];
[pool release];
}
-(void) Done {
[self.tableView reloadData];
}
Hope it will resolve your problem...Good Luck

MWFeedParser stringByReplacingXmlEntities memory leak

NSURL *xmlUrl = [[NSURL alloc] initWithString:#"http://www.xml-document.xml"];
NSString *converted = [[NSString alloc] initWithContentsOfURL:xmlUrl encoding:NSISOLatin1StringEncoding error:nil];
converted = [converted stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
converted = [converted stringByDecodingXMLEntities];
The last line takes up 98.3% of the memory in Instruments > Leaks.
And it's smashing my Log window with:
__NSAutoreleaseNoPool(): Object 0x6d10ba0 of class UIView autoreleased with no pool in place - just leaking
Why? I think that method has worked good before...
After some more googling I found that it has to be because of these methods:
[self performSelectorInBackground:#selector(load) withObject:loadingIndicator];
[self performSelectorInBackground:#selector(getEvents) withObject:nil];
So I've tried allocating an NSAutoReleasePool and the release it after the work is done in the methods.
Now i receive EXC_BAD_ACCESS message.
This did not happended before I decided to run those methods in the background. So what's the problem here?

iPhone: Can't set object received from thread in NSMutableDictionary

I've got a thread (specifically an NSOperation) that runs to load some images for me for a scroll view when my main view asks for them. Any number of these NSOperations can be queued at once. So it goes with the filepath I give it and loads the image from the disk (as UIImages) and then sends the object back to my mainview by using performSelectorOnMainThread: and passing my mainview an NSDictionary of the object, and an image ID value. My main view is then supposed to insert the image object and the image ID string into an NSMutableDictionary that it has for the mainview to be able to use. I've verified that the NSMutableDictionary is allocated and initialized fine, but when the method the NSOperation calls tries to add the objects to the dictionary nothing happens. I've verified that the object and string i get from the dictionary the thread sent me are not null or anything but yet it doesn't work. Am I not doing something right or using a bad technique? What would anyone suggest to do in a situation like this where I need to add UIImages to an NSMutableDictionary from a thread? Thanks so much!
Here's the NSOperation code I use:
- (void)main {
NSString *filePath = [applicaitonAPI getFilePathForCachedImageWithID:imageID andSize:imageSize];
UIImage *returnImage = [[UIImage alloc] initWithContentsOfFile:filePath];
if (returnImage) {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:2];
[dict setObject:returnImage forKey:#"IMAGE"];
[dict setValue:[NSString stringWithFormat:#"%d", imageID] forKey:#"IMAGE_ID"];
NSDictionary *returnDict = [[NSDictionary alloc] initWithDictionary:dict];
[dict release];
[mainViewController performSelectorOnMainThread:#selector(imageLoaderLoadedImage:) withObject:returnDict waitUntilDone:NO];
[returnDict release];
}
}
And here's the method on the main thread:
- (void)imageLoaderLoadedImage:(NSDictionary *)dict {
UIImage *loadedImage = [dict objectForKey:#"IMAGE"];
NSString *loadedImage = [dict valueForKey:#"IMAGE_ID"];
[imagesInMemoryDictionary setObject:loadedImage forKey:loadedImageID];
[self drawItemsToScrollView];
}
[mainViewController performSelectorOnMainThread:#selector(imageLoaderLoadedImage:) withObject:nil waitUntilDone:NO];
You're not passing returnDict as the parameter to the method. You're passing nil.
A couple of other thoughts:
you don't need to create returnDict. You can just use dict as the method parameter.
you're leaking returnImage.
edit
Since you apparently are passing returnDict as the parameter to the method, my other guess would be that mainViewController is nil. Other than that, your code looks functional.