I have this same code at the end of each view to go to the next:
- (IBAction)proceed2 {
StepThree *one = [[[StepThree alloc] initWithNibName:#"StepThree" bundle:nil] autorelease];
one.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:one animated:YES];
}
This has worked in every view except this one, and all of my code looks exactly the same except for different step numbers (not always StepThree). I imported "StepThree.h" just as I did in all of them... why is this one giving me problems?
By the way, it is in the line
[self presentModalViewController:one animated:YES];
and the error is "Thread 1: Program received signal: "SIGABRT"."
The code you post seems correct.
The problems arises presumably due to something in StepThree implementation.
A good way to diagnose this kind of bad behavior is enabling "zombies" detection. See here for details.
Related
I'm trying to debug some code. I ran the static analyzer, and thought I fixed a memory leak, and now I get an error when I switch between two tabs. Here is my code when I switch between the 2nd tab and first tab:
if (_sortButton != nil) {
self.SortButton = nil;
NSMutableArray *barItems = [[self.MainToolbar items] mutableCopy];
[barItems removeObjectAtIndex:0];
[self.MainToolbar setItems:barItems]; // bad access here
[barItems release];
}
I keep getting the EXC_BAD_ACCESS on the self.MainToolbar setItems line. I added the NSZombieEnabled as an environment variable, set a break point at that bad access line, but I do not get anything printed to the console when either stepping after the breakpoint, hitting continue after the breakpoint, etc. Am I using this correctly? Thanks.
Far easier to use than NSZombieEnabled, is to use Profile instead when running and select the NSZombie instrument.
This requires XCode4.
Please try adding a ,nil at the end of a list of objects for the NSArray.
[self.MainToolbar setItems:barItems,nil]
I have ONE viewController that is giving me a problem...
UIViewController *nextController = [[NextView alloc] initWithNibName:#"NextView" bundle:nil];
[currentPageController.view removeFromSuperview];
[self.view addSubview:nextController.view];
My app crashes here with an EXC_BAD_ACCESS.
Does anybody have ANY idea what could cause this?
Thanks in advance!
UPDATE
After using Breakpoints and stepping through the code, the problem seems to be with this bit of code in the viewDidLoad of my viewController:
NSString *noteToSet;
if ([Settings isData]) {
noteToSet = [NSString stringWithFormat:#"Data, "];
}
if ([Settings isGeom]) {
if ([noteToSet isEqualToString:#""]) {
noteToSet = [NSString stringWithFormat:#"Geom, "];
} else {
noteToSet = [noteToSet stringByAppendingFormat:#"Geom, "];
}
}
Anybody see a problem there?
Thanks so much!
FIXED
Fixed it by initializing the string with the blank value #""
noteToSet = [NSString stringWithFormat:#""];
So the first part of the answer is - if your viewController won't load and you have no idea why - check the code in viewDidLoad, that's where my issue was and it drove me crazy trying to figure out what was wrong with the viewController itself when it was really an NSString issue in the viewDidLoad all along.
The second part is that you can't compare an NSString to a blank value using [stringName isEqualToString:#""] unless you got that string from NSUSerDefaults or unless you first set the string to be equal to #"".
I don't see anything in the posted code that'd cause the exception. However, both pieces of code that you posted contain the lines:
currentPageController = nextController;
[currentPageController retain];
[nextController release];
Since the first line makes currentPageController point to the same object as nextController, the second and third lines cancel each other out. You might as well write:
currentPageController = nextController;
and leave it at that. A similar misunderstanding at some other point in the code could easily cause you to miss a retain or release once too often and cause the sort of bad pointer that you seem to be seeing.
EXC_BAD_ACCESS is often caused by poor memory management. Go to the Build Menu in Xcode and Profile it (in the simulator) using Allocations. Then go in and make sure you have Zombies Enabled. Run the app in the simulator and point it to where you get the error. Instruments should then tell you where the bad memory management is. If you still can't get it, then tell us what you're getting.
Here's a guide: http://www.markj.net/iphone-memory-debug-nszombie/
Hi I'm a new bie in Game Center for iOS. I'm trying to add the multiplayer feature using matches to my game and following the documentation.
So far I reached a point where 2 of my clients can successfully get a match, i.e. the matchmakerViewController:didFindMatch callback is called and a GKMatch object is delivered.
However after that I seems to be stuck there forever, because according to the documentation, I'll have to wait until all the players (2 in my case) are actually connected before starting my game. But it seems the match:player:didChangeState callback is never called to indicate a successful connection. Well, I'm sure my clients are all in the same wifi network ( or is it a must?) Could any one enlighten me on this case? Do I have to do any extra things to make the clients to connect? Thanks a lot for the help!
So I was running into this and the solution (for me) was somewhat embarrasing. I had copied and pasted a bunch of the code from the Apple docs..and they left out an obvious step. They never actually set the match's delegate!
My code now is:
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *)match {
[self dismissModalViewControllerAnimated:YES];
self.myMatch = match; // Use a retaining property to retain the match.
self.myMatch.delegate = self; // THIS LINE WAS MISSING IN THE APPLE DOCS. DOH.
// Start the game using the match.
NSLog(#"Match started! Expected Player Count:%d %#",match.expectedPlayerCount, match.playerIDs);}
Once I actually set the match delegate, the functions get called. Doh.
When you get the GKMatch object, be sure to check the expectedPlayerCount property. It is possible that the other player is already connected, and thus you will not get a match:player:didChangeState on the delegate.
I have had the same problem with a friend. The solution was quite strange but it works afterwards. On all devices you have to enable the Notifications (Sounds/Alerts/Badges) for the Game Center inside the Settings/Notifications options. Afterwards we could establish a connection and did receive a match object
Inside your callback matchmakerViewController:didFindMatch
Add this code then you'll see the callback "match:player:didChangeState" being called by GC
GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease];
request.minPlayers = 2;
request.maxPlayers = 2;
[[GKMatchmaker sharedMatchmaker] addPlayersToMatch:match matchRequest:request completionHandler:^(NSError* error) {
if(error)
NSLog(#"Error adding player: %#", [error localizedDescription]);
}];
It was working all along. The only difference is that... when you use invites the event "didChangeState" doensn't get called. You're connected without notice and you can start to receive data. I never tried to send/receive data... cuz i was expecting the event first, but i did send something by mistake one time, and it worked. :)
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *) match {
//Dismiss window
[self dismissModalViewControllerAnimated:YES];
//Retain match
self.myMatch = match;
//Delegate
myMatch.delegate = self;
//Flag
matchStarted = TRUE;
//Other stuff
}
- (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state {
//This code gets called only on auto-match
}
The above code works as expected.
Make sure that you've set your class as the delegate for GKSession. The class will need to implement the GKSessionDelegate protocol... otherwise, it'll never receive this callback. Here's the protocol reference. Hope this helps!
I just cannot imagine what the hell the problem could be.
I made a pretty app, and decided to use only CALayers to "render".
When I saw that the changes in the position property gets animated, decided to implement a custom getter-setter "abstract" property called tanCenter to set the position without animating.
-(void) setTanCenter: (CGPoint) sentCenter
{
//Remove any transactions.
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
//Set position.
self.position = sentCenter;
[CATransaction commit];
//Set value.
tanCenter = sentCenter;
}
-(CGPoint) tanCenter { return tanCenter; }
Since I merged this into the project, it crashes without any "understandable" (for me) error message. I can see only those "out of scope"-s. I cant even get this tanCenter property NSLog-ged without crash.
Help me, Obi-Wan Kenobi; you're my only hope.
If you run in the debugger (Command-Y) and make sure you have global breakpoints enabled, the debugger should stop at the place where the crash occurred giving you an idea of what is nil or over-released.
hey I had the same problem till now. Finally I have found my bug after investigating 2 weeks of bug tracking (it really sucks)
maybe my problem helps you:
I started with a TableView that opens on click another view. So I created in:
-(void)tableView:didSelectRowAtIndexPath:
first the controller for the other view and set the value for a global variable:
SomeView *dtview = [[SomeView alloc] initWithNibName:#"SomeView" bundle:nil];
dtview.lblTitle = cl.textLabel.text; // cl is the cell
[self presentModalViewController:dtview animated:NO];
[dtview release];
So opened the other view and done much functions with much memory usage :)
When I after that close the other view and go back to the table and scroll some times the App terminates with the message "out of scope"
I searched really, really long to find out what was the effect. It seems that when the other view is released also the text of the first table is released.
After putting a copy to the call it worked for me:
dtview.lblTitle = [cl.textLabel.text copy];
For int and bool the first solutions works fine, because these aren't objects but for NSObject's you should copy the values to another view.
I am building a game that pulls images randomly. After doing some testing I have realized if the same image is called twice, it crashes. I learned this by after completing the first game, I returned to the games main menu and selected to play again. I ended up getting an image which was already displayed to me in my previous game and a second later my app crashed. I did some testing and made the same image show up twice during my first game, and it crashed a second after the image was displayed a second time.
Here is a sample code. "idNum" and "timer" are declared in the .h file so they are global. As you can see I have NSTimer that runs every second to randomize a new image to be pulled. Works find until an image is trying to be shown for a second time. Say I get a random order of 1,3,2,5,3. It will crash on the second 3.
Can you not call an image twice? I can only think that this is a caching issue, I am not sure how to release the image cache. I get the error objc_msgSend. Sorry not very good at debugging crashes.
//idNum = the randomly generated integer
//pictures are called by numbers ex(1.jpg, 5.jpg)
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(timeCounter) userInfo:nil repeats:YES];
-(void)timeCounter {
time = time + 1;
idNum = (arc4random() % 5);
NSString * imgIDnum = [[NSString alloc] initWithFormat:#"%d", idNum];
imgMain = [NSString stringWithFormat:#"%#%#", imgIDnum, #".jpg"];
[imgIDnum release];
UIImage * daImg = [UIImage imageNamed:imgMain];
[imgView setImage:daImg];
}
You should provide more information about the crash. Is it in the +imageNamed: line above, or perhaps in -setImage:?
The most likely cause is that you are over-releasing the UIImage. For instance, if you're calling [daImg release] after the above code, then you would get this behavior because you would be over-releasing something that the UIImage class is caching. This wouldn't cause a crash until the situation you describe.
I've seen a really entertaining version of this bug: a teammate of mine was over-releasing an NSNumber (it happened to be for the integer 2 most of the time). NSNumbers are cached internally, so the next time he created an NSNumber for the integer 2, in an unrelated part of the program, it would crash. Any other number was fine, but try to NSLog() a 2, and boom.
Well I am sorry to say that I have fixed the issue and have no idea how. I ended up re-writing majority of that code, adding, removing and changing some snippets around to be more memory management friendly. When I went to run it again things were perfectly fine. Sorry for no solution. If someone else comes across this problem, let me know I will try and help.