I am creating an app for the Iphone/Itouch, but I keep on running into a couple of major leaks that just crash the app. In my game, right when I press play (from the home screen)It goes to another page that has the game on it. But, right after it appears, ind the console I get a Warning: Memory level=1. What could be happening? Here is my ViewDidLoad Method:
-(void)viewDidLoad {
[super viewDidLoad];
array = [[NSMutableArray alloc] initWithCapacity:100];
bulletArray = [[NSMutableArray alloc] initWithCapacity:100];
pos = CGPointMake(0.0,-5.0);
NSString *path = [[NSBundle mainBundle] pathForResource:#"GloriousMorning" ofType:#"mp3"];
AVAudioPlayer *theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
//float effects_Volume = [[NSUserDefaults standardUserDefaults] floatForKey:#"effectsVolume"];
//theAudio.volume = effects_Volume;
[theAudio play];
}
And also, a second question, since my game is a shooting game, the user presses a button titled "Fire". But, every time I test my app on a device, It crashes when I press the fire button. Here is my code for the fire button.
-(IBAction)Fire {
NSString *path = [[NSBundle mainBundle] pathForResource:#"gunShot" ofType:#"mp3"];
AVAudioPlayer *theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
//float effects_Volume = [[NSUserDefaults standardUserDefaults] floatForKey:#"effectsVolume"];
//theAudio.volume = effects_Volume;
[theAudio play];
//IBOutlet UIImageView *newBullet = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Bullet.png"]];
UIImageView *newBullet = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Bullet.png"]];
newBullet.frame = CGRectMake(0, 0, 10.0, 10.0);
newBullet.center = CGPointMake(239.0, 236.0);
[bulletArray addObject:newBullet];
[self.view addSubview:newBullet];
}
First, I create a sound. Then, I place a bullet right where the gun is currently located, and add it to an array so that every .01 of a second, in another bit of code, I can run through the array and check every bullet to detect collision.
Please tell me what I am doing wrong. Thanks!!!
The error when I click the Fire Button that makes the app crash is this:
GDB: Data Formatters temporarily unavailable, will retry after a 'continue'(unknown error loading shared library "
And Also I think I am making a huge leak when I try to play the audio, at least that's what someone told me. (If that is the case, please tell me how to fix it)
You alloc'd theAudio so you need to release it when you are done. Might be better to make that a ivar so you don't have to set up and tear down the audio every time they press the fire button.
Related
I'm using ShareKit to share objects to Twitter, Facebook, and Email. Twitter and Facebook works fine, but email doesn't. And I don't really know why.
It seems like it works quite randomly.
I set it up like this:
[self.customView.shareButton addTarget:self action:#selector(sharePost:) forControlEvents:UIControlEventTouchUpInside];
- (void)sharePost:(UIButton *)sender
{
NSURL *url = [NSURL URLWithString:self.currentPost.link];
// Add image.
NSString *imageUrlString = [NSString stringWithFormat:[link]];
NSURL *imageUrl = [NSURL URLWithString:imageUrlString];
UIImageView *postImage = [[UIImageView alloc] init];
[postImage setImageWithURL:imageUrl];
SHKItem *item = [SHKItem image:postImage.image title:[NSString stringWithFormat:#"%#", self.currentPost.title]];
[item setURL:url];
[item setMailBody:[NSString stringWithFormat:#"%# %#", self.currentPost.title, self.currentPost.link]];
// Get the ShareKit action sheet
// This works
SHKActionSheet *actionSheet = [SHKActionSheet actionSheetForItem:item];
// ShareKit detects top view controller (the one intended to present ShareKit UI) automatically,
// but sometimes it may not find one. To be safe, set it explicitly.
[SHK setRootViewController:self];
// Display the action sheet.
[actionSheet showInView:self.view];
}
Any ideas or what I'm missing or doing wrong?
Try to change the RootViewController and view you are using:
[SHK setRootViewController:self.view.window.rootViewController];
[actionSheet showInView:self.view.window.rootViewController.view];
Most likely your view controller hierarchy is somewhat messed up.
Ive been beating my head up against the all trying to figure out a weird sound issue in my program. I will post the code below. As a brief description I have a function that gets passed a variable and it takes that and decides which category of sound it should play, within that function I have multiple sounds of reach category so I use an arc4random statement then run that through a switch statement. What keeps happening is that it will play two sounds from the case statement instead of just one, most times if I call it twice with my button push the second time it will play the sound from the first time and a new sound, other times it plays the same same over the top of each other but with a slight delay. I put in a breakpoint in the switch and when it double plays it only goes through the switch once which is really confusing. One thing to note is right before this I do play another sound but it uses a separate AVAudioplayer and path variable so that shouldn't be an issue as it never plays the second sound as the other sound I'm playing. I'm only calling the function once when I press the button so I'm not sure why it does this. I have tried putting the *path and *avaudioplayer variables inside the function but it won't play at all. Searching here it seems as though arc deallocs it before it gets a chance to play it. I ended up trying to put it at the top of my .m file as a global variable then just set the actual path and play the sound within the switch. The sound will play but it plays twice.. Hopefully someone can help me out. I tried putting the avaudioplayer definition as a property as well and it does the same thing. Here is my code snippet. And thanks in advance ...
in the .m file
// Just below my synthesize statements
NSString *path;
AVAudioPlayer *theSound
// My code that I call when the button is pressed
[self playVoice:#"buyVoice"];
// The playVoice function
- (void)playVoice:(NSString*)voiceNum;
if ([voiceNum isEqualToString:#"buyVoice"]) // Bought an Item Time for a voice
{
// play coin sound
[self coinSound];
// play random buy phrase and coin sound
int phraseNumber = 0;
phraseNumber = arc4random() %(3);
switch (phraseNumber)
{
case 0:
{
path = [[NSBundle mainBundle] pathForResource:#"sndBuy1" ofType:#"m4a"];
theSound =[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath: path] error:NULL];
[theSound setNumberOfLoops:0];
[theSound play];
break;
}
case 1:
{
path = [[NSBundle mainBundle] pathForResource:#"sndBuy2" ofType:#"m4a"];
theSound =[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath: path] error:NULL];
[theSound setNumberOfLoops:0];
[theSound play];
break;
}
case 2:
{
path = [[NSBundle mainBundle] pathForResource:#"sndBuy3" ofType:#"m4a"];
theSound =[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath: path] error:NULL];
[theSound setNumberOfLoops:0];
[theSound play];
break;
}
case 3:
{
path = [[NSBundle mainBundle] pathForResource:#"sndBuy4" ofType:#"m4a"];
theSound =[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath: path] error:NULL];
[theSound setNumberOfLoops:0];
[theSound play];
break;
}
}
}
set this code before u play the Audio sound
This will reset the player to the beginning:
[theSound setCurrentTime:0.0];
[theSound play];
try this
fairly new to Objective-C and iOS development (coming from PHP) and I have a relatively simple question that I can't seem to find an answer to:
I am following along with an example for split View design where a web page is loaded into the Detail View when a user clicks an item in the master view. I got all this working, but would like to substitute web view for an image. So I've amended the app to load a UIImage instead of a WebView. What I'm looking for is the equivalent to this code:
NSString *urlString = [pagesAddress objectAtIndex:indexPath.row];
NSURL *url = [NSURL URLWithString:urlString];
// these 2 is where I get lost with the images.
NSURLRequest = *request = [NSURLRequest requestWithURL:url];
[detailViewController.webView loadRequest:request];
I came up with this:
NSString *imageName = [pagesAddress objectAtIndex:indexPath.row];
UIImage *myImage = [UIImage imageNamed:imageName];
// missing the last 2 calls: one to tell Xcode that it's an image "request" I want and the second to load the actual image (based on it's name that is already in an array) into the ImageView.
Thanks.
PS
I tried this:
NSString *imageName = [pagesAddress objectAtIndex:indexPath .row];
[detailViewController.imageView setImage:[UIImage imageNamed:imageName]];
And it shows just the first image, then crashes when I try to show the last one.
In the end, the solution were those 2 lines when I amended the code:
NSString *imageName = [pagesAddress objectAtIndex:indexPath.row];
[detailViewController.imageView setImage:[UIImage imageNamed:imageName]];
Notice that I had to change the setImage to convert the NSString to a UIImage or Xcode would complain. It turns out it was crashing because in the array where I had the image names, I had put 3 images into one entry (basically I forgot the commas!) so it was out of range.
Tim:
This line you gave me
UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
is unnecessary because I already have a view created, it would create another view which I never used. Also, replacing it with CGRect seems overkill if I already have a UIImage placeholder no?
In any case, it works now and I'm very grateful for all the help. iPad development with Objectve-C is a very thorny road and I expect I'll be bugging you guys some more.
Cheers.
Try this:
UIImage *myImage = [[UIImage alloc] initWithData:[NSData dataWithConentsOfURL:[NSURL URLWithString:urlString];
// don't know if you already got the following?
UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
[imageView setImage:myImage];
[self.view addSubview:imageView];
The first line is synchronous (= blocking), so in production, you should rather use - [NSURLRequest start] for this (but that's a bit more complicated).
Or use this for your local images:
UIImage *myImage = [UIImage imageNamed:imageName];
// Now, follow the same steps as in the first code-example, just skip the first line.
Try this (on iOS 4.0 and later):
// Execute a block of code on a background thread.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^(void)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
UIImage* image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
// When IO is done and image created, set it on the main thread.
dispatch_async(dispatch_get_main_queue(),
^(void)
{
imageView.image = image;
});
[pool release];
});
I want to play the music from internet by url.
I create a simply project that has one button with the following code:
NSURL *url = [[NSURL alloc] initWithString:#"http://someURL.mp3"];
NSError **err;
QTMovie *movie = [[QTMovie alloc] initWithURL:url error:err];
[movie play];
It works but with some delay (I think because it waits while file has been fully downloaded).
So what I need to do that the music starts to play immediately (when, for example, 10% of file has been downloaded)?
Use -[QTMovie autoplay] to automatically play the music once enough data has been downloaded.
In your case:
NSURL *url = [[NSURL alloc] initWithString:#"http://someURL.mp3"];
NSError **err;
QTMovie *movie = [[QTMovie alloc] initWithURL:url error:err];
[movie autoplay];
From the QTMovie class reference:
The autoplay method configures a QTMovie object to begin playing as soon as enough data is available that the playback can continue uninterrupted to the end of the movie.
If you can consider displaying a Quicktime window over your app, you can use this code :
NSString *url = #"http://someURL.mp3";
UIWebView* tempAudioPlayer = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
[tempAudioPlayer loadHTMLString:[NSString stringWithFormat:#"<iframe frameborder=\"0\" width=\"0\" height=\"0\" src=\"%#\"></iframe>", url] baseURL:nil];
[self addSubview:tempAudioPlayer];
I first create a UIWebView which will not be displayed. Then I loadHTMLString a <iframe> in it, with the URL of my file as the src value. And I add it to my view. Quicktime appears immediately.
I am developing a swipe based application. On each swipe a page will appear containing a video with some other asset. I am using the following code to do this for me on each swipe.
NSArray *file = [videoFile componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"."]];
NSString *moviePath = [[NSBundle mainBundle] pathForResource:[file objectAtIndex:0] ofType:[file objectAtIndex:1]];
if (moviePath != nil)
{
//self.videoTimer = [NSTimer scheduledTimerWithTimeInterval:delayTime target:self selector:#selector(playVideo:) userInfo:nil repeats:NO];
self.theMovie = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:moviePath]];
self.theMovie.view.frame = self.bounds;
self.theMovie.moviePlayer.scalingMode = MPMovieScalingModeAspectFit;
self.theMovie.moviePlayer.controlStyle = MPMovieControlStyleNone;
self.theMovie.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
[self addSubview:self.theMovie.view];
[self.theMovie release];
}
else
{
[AssetValidator alertMissingFileInfo:videoFile];
}
This works fine.
My problem is that each time I swipe video starts with a delay and black screen.
Please guide how to solve this problem.
Regards.
How big are the movies? If their size is big then it's OK. There is a solution but it's quite irrational - load all the movies to memory during app startup and runtime. Otherwise (if the movies are quite big), the delay will happen anyway.
We can use a background Image to avoid black screen.