I am developing an iOS application with Rubymotion which worked pretty fine until i added a new UIViewController. I have added the controller via xcode and have got just a UITextField as an element in it. On running the simulator and on displaying this particular scene, I get an instance of NSError. I also dont see the UITextField element in my screen.
Can any one please explain as to what it is and how do i handle the NSError and make sense out of it?
Any help at this point would be of great help.
UPDATE: I am getting the NSError instance every time my app is launched first, no matter what the controller is. I had upgraded to Xcode 5.1 yesterday. Wonder if that has something to do with the error.
UPDATE 2: This was result of a confusion on my part. I had assumed the NSError to have been raised after upgrading to Xcode 5.1 and thought it was some bug. The reason being was that I had had started using push notifications at the same time as I had upgraded to 5.1. As push notifications don't work in simulators, the NSError was being returned by the simulator. Messed it up big time and spent quite a few hours trying to debug this problem.
NSError is a class and it is used as the preferred way to handle errors in objective-c. Usually it works like this:
You declare a NSError pointer and sends the address to that one in as a parameter to a method that might fail. If something goes wrong in the method a NSError object is created and populated with info about the error and when the methods returns you can check the error object to se if anything went wrong.
NSError *error;
[someObject someFunctionWithParam:paramOne andError:&error];
if ( error ) {
// Here you can inspect the error and act accordingly
NSLog(#"%#", [error localizedDescription]);
}
If you are the one implementing a method it usually looks something like this.
- (void)someFunctionWithParameter:(NSString *)argOne andError:(NSError **)error {
// something goes wrong
*error = [NSError errorWithDomain:#"SomeDomain" code:500 userInfo:#{#"infoKey": #"some info"}];
}
So about the title of your question. There is no catching NSError's since they are not thrown. Only exceptions are thrown.
Related
SITUATION I am trying to figure out the best practices for error handling with the parse.com iOS SDK. I have read the parse docs and they do a great job of documenting how to check for connectivity to parse and if objects can be found, but my question would be what do I do then?
EXAMPLE
[object saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if ([error code] == kPFErrorConnectionFailed) {
//COULD NOT REACH PARSE
//SO WHAT NOW?
}
else {
//EVERYTHINGS COOL
}
}];
SO WHAT NOW? Am I supposed to have this on an NSTimer and fire this off again in 5 minutes to see if we can reach parse then?
If saving objects is as important as it seems to be for your case, then this could be a solution, instead of using an NSTimer:
In the SO WHAT NOW? block, just call the method that saves this object recursively. If you ever get an error other than ConnectionFailed you could handle that appropriately, but if you're just worried about saving this even if the first attempt fails, this could be a way.
I'm developing a turn based game for iOS with a custom interface and i discovered a very odd problem with my matchmaking interface. The following code is used to display a list of active matches, i authenticate the user, then get the list of matches and the last step is to load the match so i can display all the info.
The problem appears when i build the app, go to the matchmaking view controller and leave it alone for 5 minutes; then when i try deleting a match i get an error in loadingMatchWithID:
Error Domain=NSCocoaErrorDomain Code=4097 "The operation couldn’t be completed. (Cocoa error 4097.)
The code works fine every time, deleting, creating matches, refreshing, but if i leave the view controller alone for 5 minutes and then try to delete i get the error. The odd part is the that the localPlayer passes an authentication test, and loads correctly the matches array then stops in loading the match.
One other thing happens, if the error appears and i push the home button and open back the app, everything words again and the matches are loaded correctly.
I think i a problem with the authentication, but where is the mistake ?
UPDATE: The issue appears in iOS7, but in iOS6 it works !
[localPlayer authenticateWithCompletionHandler:^(NSError *error)
{
if (error)return;
[GKTurnBasedMatch loadMatchesWithCompletionHandler:^(NSArray *matches, NSError *error)
{
for (int i = 0; i < matchesArray.count; i++)
{
[GKTurnBasedMatch loadMatchWithID:[[matchesArray objectAtIndex:i]matchID] withCompletionHandler:^(GKTurnBasedMatch *updatedMatch, NSError *error)
{
if (error != nil)
{
NSLog(#"Error: %#",error.description);
}
}];
}
}];
}];
I found what was the issue after many days of searching and testing everything. The problem was with quitting and then removing a match, the removeWithCompletionHandler: was inside the participantQuitInTurnWithOutcome: and somehow these actions would log out the player from game center without any notice, and the odd thing was that all the .isAuthenticated test would succeed.
Probably the most frustrating part was that the code worked for the most part, and worked every time on devices below iOS 7.
The full error is:
app(85540,0x38661a8) malloc: *** error for object 0x11214f84:
incorrect checksum for freed object - object was probably modified after being freed.
So I'm getting something that is quite hard to replicate and I suspect is has something to do with the way I have my block set up. What I'm trying to get is the current online status of gamers on Xbox Live, so I allocate 2 NSMutuableDictionaries in viewDidLoad. onlinePlayers is for holding the online status values of the gamers so it's not checked over and over again in cellForRowAtIndexPath when scrolling up and down. checkedPlayers is to prevent multiple calls going out trying to get the status of the same player. Anyway, if I keep launching the simulator over and over again, it will be fine 29/30 launches, but it always crashes at least once on launch with the above error when I'm trying to set the online status value for a gamer:
NSString* gamertag = cell.gamerTagLabel.text;
if (![_checkedPlayers containsObject:gamertag]) {
[_checkedPlayers addObject:gamertag];
[Utilities processJSONDataWithGamertag:gamertag andBlock:^(NSData *jsonData) {
id onlineStatus;
NSDictionary *allXboxAttributes = [Utilities returnJSONObject:jsonData];
// Get current Xbox Live Data
if ([allXboxAttributes objectForKey:#"data"]) {
NSDictionary *dataXboxAttributes = [allXboxAttributes objectForKey:#"data"];
onlineStatus = [dataXboxAttributes objectForKey:#"online"];
// Crashes on the line below
[_onlinePlayers setObject:onlineStatus forKey:gamertag];
// Return to main thread and update online status
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}];
}
If it helps for some reason, the value being returned from dataXboxAttributes is a BOOL. Any help would be much appreciated. Thanks!
You are getting the error in that method but the problem might be elsewhere.
To find the source of the problem, in XCode go to Product > Scheme > Edit Scheme, and under Diagnostics tab enable all the Malloc settings and Guard Malloc.
With that, run your application again, and XCode will stop at the line causing the problem.
from your code it looks like the completion block of processJSON isnt always on the main thread, synchronize access to onlinePlayers.
#synchronized will do I guess
I'm building a turn based game kit application and I'm saving and retrieving data using:
saveCurrentTurnWithMatchData:jsonData completionHandler:^(NSError *error)
loadMatchDataWithCompletionHandler:^(NSData *matchData, NSError *error)
I Get all the matches using this:
[GKTurnBasedMatch loadMatchesWithCompletionHandler:^(NSArray *matches, NSError *error) {
and save each of the matches to an array and call the laodMatchData method when I need it. The problem is that the completion handler never returns anything. I guess it's stuck gettings the data and never gets back to me. It loads sometimes but more often than not, it just keeps loading.
Am I missing something?
The problem was with iOS7 beta 1. The problem is solved now.
I developed an ios app that had a:
NSError *error;
instead of:
NSError *error = nil;
It worked fine in while I was debugging in the simulator and debugging on the device while connected. The moment I archived it and sent it into TestFlight to deploy for testing, I started getting Unknown Signal errors coming up in the crash log.
Why does this happen?
This happens because you have an uninitialized pointer. It does not crash as long as you get lucky, but using such pointers is undefined behavior.
To clarify on dasblinkenlights answer, this is declaring a variable:
NSError *error;
... and this is declaring AND assigning a variable
NSError *error = nil;
When you use it the first way and try to access it without ever setting it to something, the value it is pointing at is known as "garbage" It is a pointer to some other stack of memory, and accessing it will almost always make your app crash. Thus, it is always best practice to assign a value to your variable as above, or shortly after.