I am currently getting this crash log in the console: - iphone

2011-12-01 18:10:36.932 AVCam[3987:17903] *** -[UIImage _isResizable]: message sent to deallocated instance 0xdf7e360
Current language: auto; currently objective-c
The Code is
UIImageView * firstView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 240)];
[firstView setContentMode:UIViewContentModeScaleAspectFill];
firstView.image = firstPhoto.photo;
[firstBlock addSubview:firstView];
[firstView release];
Does anyone know what this means? What could be the cause of it?
Thanks!

The problem should be here:
firstView.image = firstPhoto.photo;
What is firstPhoto? When does it get released? I guess it gets deallocated before it becomes the content of that UIImageView.
You'll probably have to send a `[retain]` message, something like:
firstView.image = [firstPhoto.photo retain];

Related

Perform selector:withObject:afterDelay firing immediately, no delay

I have a very strange error that I have never seen before. I have used this code hundreds of times before, but for some reason, the afterDelay is being completely disregarded.
My Code:
- (void)runIntro
{
if([self introDone])return;
UIImageView* back = [[UIImageView alloc] initWithFrame:[[AppDelegate shared] frame]];
[back setImage:[[AppDelegate shared] bgImage]];
[back setContentMode:UIViewContentModeScaleAspectFill];
[self.view addSubview:back];
UIImageView* target = [[UIImageView alloc] initWithFrame:CGRectMake(([[AppDelegate shared] width]-250)/2.0, ([[AppDelegate shared] height]-350)/2.0, 250, 72)];
[target setImage:[UIImage imageNamed:#"bpside.png"]];
[self.view addSubview:target];
Parabolic* wally = [[Parabolic alloc] initWithFrame:CGRectMake(([[AppDelegate shared] width]-200)/2.0, ([[AppDelegate shared] height]-314)/2.0+250, 200, 200)];
[wally setImage:[UIImage imageNamed:#"wallyside1.png"]];
[self.view addSubview:wally];
[self performSelector:#selector(moveWallyIntro:) withObject:wally afterDelay:1];
[self performSelector:#selector(moveWallyIntro:) withObject:wally afterDelay:2];
}
- (void)moveWallyIntro:(Parabolic*)wally
{
[wally runPBM:50 withDY:300 withDuration:0.5];
}
I know that all of the other code is working properly, but for whatever reason, the selectors are being performed immediately, which causes a major problem. This code is being run at the end of the viewWillAppear method. I have programmed this way many times before and this is the first time I've seen this happen.
UPDATE:
If I remove the code that adds the back UIImageView, this no longer is a problem. How can I add a giant image (3000x2000) in aspect fill format like this so it doesn't cause the program to hang? I'm using the same background image for iphone, ipad, etc., so it needs to be large for the retina iPads...

Problem while using Multi - threading in iPad programming (for loading large number of images)

i am supposed to load large number of images on to a scrollview which, i suppose would take some time and memory. So, i used a separate thread to load these images in the background. I have used the following multi threading method
[NSThread detachNewThreadSelector:#selector(prepareSliderView) toTarget:self withObject:nil];
to load the images on a separate thread. While implementing this method i am getting the following messages in my GDB
NSAutoreleaseNoPool(): Object 0x10647180 of class NSPathStore2 autoreleased with no pool in place - just leaking
NSAutoreleaseNoPool(): Object 0x10647300 of class NSPathStore2 autoreleased with no pool in place - just leaking
NSAutoreleaseNoPool(): Object 0x10646a00 of class NSCFString autoreleased with no pool in place - just leaking
NSAutoreleaseNoPool(): Object 0x10647480 of class NSPathStore2 autoreleased with no pool in place - just leaking
NSAutoreleaseNoPool(): Object 0x10646a20 of class UIImage autoreleased with no pool in place - just leaking
I had no clue what this meant as i never executed this method before. So, my questions are
1 - should i use some autoRelease pool along with this method
2 - is there any other way in which i can load large number of images with out putting a lot of load the main thread
-(IBAction)prepareSliderView{
NSLog(#"Preparing slider view");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int totalPages=[kbDataSource numberOfPagesInBook];
sliderScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height-300, self.view.frame.size.width,200 )];
sliderScrollView.contentSize = CGSizeMake(totalPages*150+((totalPages-1)*10), 200);
sliderScrollView.backgroundColor=[[UIColor blackColor] colorWithAlphaComponent:1.0];
thumbnailContentView = [[UIView alloc] initWithFrame:CGRectMake(10, 0, sliderScrollView.contentSize.width, sliderScrollView.contentSize.height)];
newPageSlider.continuous=YES;
newPageSlider.minimumValue=1;
newPageSlider.maximumValue=totalPages;
thumbnailFrame = CGRectMake(0, 25, 120, 150);
pageNumFieldFrame = CGRectMake(0, thumbnailFrame.size.height+10, thumbnailFrame.size.width, 50);
for(int i=1;i<totalPages;i++){
thumbnailView = [[UIView alloc] initWithFrame:thumbnailFrame];
thumbnailView.backgroundColor=[UIColor clearColor];
UIButton *thumbnail = [[UIButton alloc] initWithFrame:thumbnailFrame];
UILabel *pageNumField = [[UILabel alloc] initWithFrame:pageNumFieldFrame];
pageNumField.backgroundColor=[UIColor clearColor];
thumbnail.tag=i+1;
thumbnailView.tag=i+1;
id<PageDataSource> pd = [kbDataSource pageAtIndex:i];
thumbnailFrame = CGRectMake(thumbnailFrame.origin.x+150+10, thumbnailFrame.origin.y, 120, 150);
pageNumFieldFrame = CGRectMake(pageNumFieldFrame.origin.x+150+10, pageNumFieldFrame.origin.y, thumbnailFrame.size.width, 50);
[thumbnail setBackgroundImage:[pd thumbnailImageForPageNumber:i] forState:UIControlStateNormal];
pageNumField.text =[NSString stringWithFormat:#"Page %d",i];
pageNumField.textColor=[UIColor whiteColor];
[thumbnailContentView addSubview:thumbnailView];
[sliderScrollView addSubview:pageNumField];
[sliderScrollView addSubview:thumbnail];
[sliderScrollView addSubview:thumbnailView];
[sliderScrollView bringSubviewToFront:thumbnail];
[sliderScrollView bringSubviewToFront:pageNumField];
[self.view bringSubviewToFront:thumbnail];
[thumbnailView release];
[pageNumField release];
[thumbnail release];
[thumbnail addTarget:self action:#selector(navigateToPage:) forControlEvents:UIControlEventTouchUpInside];
[pool release];
}
}
For each main method that you execute in a new thread, either via NSThread or via performsSelectorInBackground:, you have to create an autorelease pool like this:
- (void)myBackgroundOperation
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Do some work.
// At the very end, release the pool.
[pool release];
}
See also: Why is there no autorelease pool when I do performSelectorInBackground
But for your task I suggest you also look into the NSOperationQueue. See for example the article Cocoa Tutorial: NSOperation and NSOperationQueue.
As the documentation says:
the method aSelector is responsible
for setting up an autorelease pool for
the newly detached thread and freeing
that pool before it exits
So, in your prepareSliderView method you need to create and release an autorelease pool:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// some work
[pool release];

NSAutoreleasePool leaking

I know this must be something simple that I am overlooking, but why is this leaking:
//add a pool for this since it is on its own thread
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//add the image
NSURL * imageURL = [NSURL URLWithString:[recipeData objectForKey:#"imagePath"]];
NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage * image = [UIImage imageWithData:imageData];
UIImageView * myImageView = [[UIImageView alloc] initWithImage:image];
//resize to make it fit the screen space
CGRect frame = myImageView.frame;
frame.size.width = 320;
frame.size.height = 357;
myImageView.frame = frame;
[self.view addSubview:myImageView];
[activity stopAnimating];
[pool drain];
[self placeItems];
I get the error:
_NSAutoreleaseNoPool(): Object 0x4e2fdf0 of class NSPathStore2 autoreleased with no pool in place - just leaking
I tried moving the placement of [pool drain] but that did nothing. I see a lot of code that looks just like this while searching Google for a cause.
Thanks for your help.
Draining the pool has the effect of releasing and subsequently deallocating it, since autoreleasepools cannot be retained. I suspect there must be some need for an autoreleasepool within placeItems (or some other place called after [pool drain]) since at that point the pool is propably gone already.
So, you might want to try commenting out the drain message to see if that will make the leak go away.
A lot of things to say here :
first, you're leaking myImageView. You have to release it after the -addSubview.
next, since you're on another thread, your [pool drain] must be at the end
last, since you're not on the main thread, you can't perform any UI operation. Try to replace [self.view addSubview:myImageView] by [self.view performSelectorOnMainThread:#selector(addSubview:) withObject:myImageView waitUntilDone:YES]. Same with [activity stopAnimating].
And like Brian said, the -drain message must be at the end of your thread.

What is wrong with my code? I'm using MBProgressHUD

I'm using MBProgress HUD and I don't know what is the problem.
I have a UIButton that shows the HUD.
This is my code:
- (void)showHUD:(id)sender {
HUD = [[MBProgressHUD alloc] initWithView:self.view];
HUD.mode = MBProgressHUDModeCustomView;
[self.view addSubview:HUD];
HUD.delegate = self;
HUD.labelText = #"No Internet Connection...";
HUD.opacity = 0.7;
HUD.customView =
[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image.png"]];
[HUD showWhileExecuting:#selector(hudWasHidden)
onTarget:self
withObject:nil
animated:YES];
}
- (void)hudWasHidden {
float progress = 0.0f;
while (progress < 1.0f) {
progress += 0.01f;
HUD.progress = progress;
usleep(50000);
}
}
Here is the Console log:
2010-06-11 17:55:26.255 Dual Search[14166:207] * -[MBProgressHUD setCustomView:]:
unrecognized selector sent to instance 0x6321220 2010-06-11 17:55:26.256 Dual
Search[14166:207] Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '** -[MBProgressHUD setCustomView:]:
unrecognized selector sent to instance 0x6321220' 2010-06-11 17:55:26.256 Dual
Search[14166:207] Stack: ( 41853515, 2505499913, 42125115, 41587990, 41584658,
13036, 2853830, 3324117, 3332879, 3328066, 2977128, 2871789, 2903111, 49860988,
41394236, 41390152, 49854621, 49854818, 2895329, 10508, 10362 )
My app always crashes when clicking the UIButton.
Thanks
This is a common crash in Cocoa code: "unrecognized selector" is very explicit in this case. MBProgressHUD doesn't have a customView property, and attempting to set it is causing the crash. The setCustomView is the implicit selector (method) being called here, and Objective-C will crash when a called method isn't there.
Not sure what to tell you about how to accomplish what you're trying to do.

How do I get a UIView to appear instantly?

I'm trying to create an activity indicator in iPhone app. The problem is that I cannot get it to appear before the actual task i want it to diplay during is already done. Is there something funky about the order in which the iPhone does stuff?
Here is my problematic code (in my app delegate):
-(BOOL)showProgressView: (NSString *) message {
self.progress = [[UIView alloc] initWithFrame:window.frame];
UIImageView *img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"squircle.png"]];
[img setAlpha:0.5];
[img setFrame:CGRectMake(94, 173, 133, 133)];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(51.5, 51.5, 30, 30)];
spinner.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
[img addSubview:spinner];
[self.progress addSubview:img];
[spinner startAnimating];
[img release];
[spinner release];
[window addSubview:self.progress];
return YES;
}
I then call this code like this:
if ([appDelegate showProgressView:#"Loading..:"])
{
//My actual code loads data and stuff here but that is not important
//drawCtrl is a UIViewController subclass that is instantiated here
UINavigationController *navController = [appDelegate navigationController];
[navController pushViewController:drawCtrl animated:YES];
[drawCtrl release];
}
The problem is that my activity indicator does not appear until the new view controller is pushed onto the navController's stack. Can I control this in some way?
Thanks in advance!
-Mats
You need to call your loading method periodically via a timer. UI changes require a trip through the event loop to be seen. I have done this usually in a timer I set up in the AppDelegate, it calls the "methodThatTakesSomeTime" every n seconds, the "methodThatTakesSomeTime" method does some work for a specified time slice and then exits which is usually about the same as the timer trigger time. This gives the event loop time to refresh the UI and also give your method time to do its stuff.
Takes some fiddling with keeping the state of the "methodThatTakesSomeTime" so it can continue on its way, but that is what it takes.