Crash (SIGABRT) while adding a view. (WebView) - iphone

I am having a crash (triggered by an exception) while adding a WebView. I haven't figured out why. And yes I have browsed the web because this is a very common problem though with no success, I found an answer saying that I should implement the DSYM to track the stack correctly, because looking at all those addresses is just meaningless (and I agree), the thing is I have no idea on how to do this. I found this: save dsym files. But I didn't figure out how to integrate it into my project, besides it looks dangerous. And yes I have NSZombie enabled too, but to no avail.
Anyway now to the point of my question. I have a button that triggers an event, the event changes a string (the URL) according to the button pressed. Then this IBAction calls on the delegate, and the delegate makes a transition to a view that has a UIWebView that will open with the URL edited by the IBAction. So I have the following code:
This is the Delegate method:
WebViewController *awebViewController = [[WebViewController alloc]
initWithNibName:#"WebView" bundle:nil];
[self setWebViewController:awebViewController];
[awebViewController release];
self.webViewController.finalURL = [NSMutableString stringWithFormat:#"%#", linkString];
[viewController.view removeFromSuperview];
// HERE happens the crash, found out using breakpoints
[self.window addSubview:[webViewController view]];
[UIView commitAnimations];
[viewController release];
viewController = nil;
This is the exact crash message:
-[WebView initWithCoder:]: unrecognized selector sent to instance 0x5718320
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '[WebView initWithCoder:]: unrecognized selector sent to instance 0x5718320'
I have the theory that it tries to make the transition but that there is no actual view to add. Though that is a wild guess. Exceptions are usually called by those kinds of things but in this case I don't see what is happening.
Thank you for your help, and forgive me if it is too dumb a question.

a guess from my side:
Do you have a view in your nib that should be a UIWebView but you changed the Class of that view to WebView?
You should first check this in interface builder.
This exception is exactly what happens if you change the Class of a view element to a class that isn't available.

The exact error is that some instance of a class called WebView (not UIWebView) at memory address 0x5718320 is being sent the message -initWithCoder:, which it doesn’t recognize. That message is called when loading views created with Interface Builder; check your nibs for a view that you’ve changed to a custom WebView class.

I had same problem, and renamed class WebView into WebViewCustom by XCode refractor/Rename feature, cleaned up project and now it works fine.

Related

controllerview stopAnimating unrecognized selector sent to instance

I am getting this error when I load a new tableview onto my navigational stack.
All of the data displays in the table that I am parsing onto it however once that has finished the app stops working and I get this error.
Just wondering if anyone knows what the problem might be? or how I might be able to debug it?
If you need more code let me know I just don't know what to provide because I'm not sure what the error refers too.
-[VehicleResultViewController stopAnimating]: unrecognized selector sent to instance 0x6a2a680
You need to post more code.
In general, an unrecognized selector error occurs when you try to invoke a method on a class that does not have the method implemented.
Is VehicleResultViewController a UITableViewController/UIViewController? Have you added the stopAnimating method? UIViewController and it's subclass, UITableViewController do not have a stopAnimating method in their default implementation.
If it's a UITableViewController or a UIViewController and you haven't added a stopAnimating method, then you're calling a method that VehicleResultViewController does not have hence the crash.
It's really hard to answer your question more accurately until you:
Post code for where you call the method
Post the header file for VehicleResultViewController so we can see what kind of class is it (or you could just tell us).
It could also be (and more probably is) that you have a UIActivityIndicatorView in your code which you want to stop spinning. In that case, are you sure it's named 'vehicleResultViewController'? Whatever your UIActivityIndicatorView is named, try calling:
[whatever_your_activity_indicator_view_is_named stopAnimating];

iOS add rootViewController to window causes delegate not found error

I'm creating an application that first loads a settings screen which displays a series of text fields and labels asking the user for input. This is all working fine.
What I then want to do is once this data has been input, it comes up with the main application interface.
What is happening though is that when I'm telling the application delegate to load the main view, it says that the viewController isn't key value complaint for the key delegate.
The code I'm using to create the viewController is:
CustomViewController *viewController = [[CustomViewController alloc] initWithNibName:#"CustomViewController" bundle:nil];
self.window.rootViewController = viewController;
If anyone thinks that UIWindow doesn't have a rootViewController property, please check the documentation. That's what I did, and it does have one.
Any help with figuring this out would be greatly appreciated.
For those that like full debug info, this is what I get from xcode.
2011-06-18 15:03:15.474 Some App[15596:207] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<CustomViewController 0x53368b0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key delegate.'
Thanks,
Matt.
Most likely you try to use delegate somewhere in your xib file, but it doesn't exist in your CustomViewController class.
Check the connections in your nib file and remove the one that connects to the non existing delegate.
The rootViewController property was only recently introduced and might not be available on devices running an older version of iOS.
You want to have a UINavigationController as the root view controller of your application and subsequent pages you simply push onto it. If you don't want animation, then do animate:NO. If you don't need a navigation bar, then hide that as well.
It is generally preferable to use one of the existing container view controllers over swapping them out yourself.

"[CALayer release]: message sent to deallocated instance" when dismissing modal view controller

I've been struggling with this for last few days and I cannot find any solution, so I ask you for advice.
I have two UIViewControllers: NewPostUIViewController and SettingsUIViewController. In the second one I have a field:
id<SettingsUIViewControllerDelegate> delegate
and the first one implements protocol
SettingsUIViewControllerDelegate
When a button is pressed the following code is executed in NewPostUIViewController:
SettingsUIViewController *settingsUIViewController = [[SettingsUIViewController alloc] initWithNibName:#"SettingsView" bundle:nil];
settingsUIViewController.title = NSLocalizedString(#"Settings", #"Settings view title");
settingsUIViewController.delegate = self;
[self presentModalViewController:settingsUIViewController animated:YES];
[settingsUIViewController release];
when I want to dismiss SettingsUIViewController I call (code in SettingsUIViewController):
[delegate settingsAreDone:sender];
and settingsAreDone looks following (code in NewPostUIViewController):
[self dismissModalViewControllerAnimated:YES];
This all concludes in:
[CALayer release]: message sent to deallocated instance 0x5a76840
I tried to debug the code by setting a breakpoint in the release methods of both view controllers, but these methods are called so often that it's hard to say what can be the cause of this problem.
Any ideas?
First, the error you're getting isn't indicating that -release is being sent to a view controller, so breakpoints in your view controllers won't help. The over-release is happening on a CALayer, which is likely part of the modal animation.
First, we start with some basics about the delegate. I don't feel great about this being the cause, but you should always start with the easy basics. Your SettingsUIViewController delegate property should be assign, not retain, so you avoid retain loops. That's probably correct already, but when it's not, you can wind up with cases where objects exist longer than you expect them to (and so can send messages after their targets have gone away). Again, probably not the issue, but easy to check and easy to fix.
Next, you should look at the stack trace at the crash. Who is calling [CALayer release]? A possible cause is that the owning view controller gets released before the animation stops. When you close the settings controller, do you immediately close the NewPost controller?

What is the difference between setting the delegate in Interface Builder vs using setDelegate:?

I'm trying to set the delegate for a scroll view using Interface Builder.
If I have code like this:
MyScrollViewDelegate * delegate = [[MyScrollViewDelegate alloc] init];
[scrollView setDelegate:delegate];
in viewDidLoad, everything works perfectly.
If I open Interface Builder, add an NSObject and set the class to MyScrollViewDelegate, then link the scrollView's delegate to my instance of MyScrollViewDelegate and inspect [scrollView delegate] inside viewDidLoad, it looks like an instance of MyScrollViewDelegate, and I can interact with it, set proprerties etc, looks good.
However, when I scroll inside the scroll view I get an NSInvalidArgumentException:
*** -[NSCFArray scrollViewDidScroll:]: unrecognized selector sent to instance 0x3d319a0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFArray scrollViewDidScroll:]: unrecognized selector sent to instance 0x3d319a0'
So, questions:
What is the difference between setting the delegate in Interface Builder vs using setDelegate:?
Why is "[NSCFArray scrollViewDidScroll:]" in the console, not, [MyScrollViewDelegate scrollViewDidScroll:]?
What could I be doing wrong?
There is no difference in setDelegate: itself.
However, you have a memory management issue. The problem is that objects don't retain their delegates (to avoid reference cycles). Your delegate is getting deallocated, and the memory is reused for an array. This is why you see a message intended for your delegate getting dispatched to an array.
You are seeing a difference because of an oddity of Interface Builder memory management. The "top-level objects", those objects that appear alongside File's Owner and Main Menu at the top level in the IB doc window, have an unbalanced retain on them. That's keeping your delegate alive in the IB case.
The solution is for something, perhaps your app delegate, to retain the scroll view delegate.
See Memory Management of Nib Objects.

Why does rotation of iPhone cause crash when _existingView message is sent to deallocated object?

I have two view controllers: MyParentViewController and MyChildViewController.
The application starts with MyParent. I push the MyChild controller to the top of the navigation stack, so that the chain is like so:
MyParent > MyChild
I log the object ID of MyChild with NSLog(#"%p", self):
2009-11-20 05:08:29.305 MyApp[2213:207] MyChildViewController instance: 0x36afc20
When I press the back button from MyChild this pops MyChild off the stack and returns me to MyParent.
When I rotate the iPhone while viewing MyParent, my application crashes with the following error message:
2009-11-20 05:08:37.671 MyApp[2213:207] *** -[MyChildViewController _existingView]: message sent to deallocated instance 0x36afc20
I have no _existingView method or instance variable in MyChildViewController.
If I pop MyChild off the stack, I think the navigation controller will release it, and I presume that it would be set to nil, and that any messages sent to it would be ignored. Though that's not happening here, obviously.
Does anyone have any ideas why my application crashes on rotation?
Is there a way to find out what is sending the _existingView message to MyChild?
EDIT
Here's the code for pushing MyChild on the stack:
MyChildViewController *_myChildViewController = [[MyChildViewController alloc] initWithNibName:#"MyChildViewController" bundle:nil];
_myChildViewController.managedObjectContext = self.managedObjectContext;
_myChildViewController.title = [_xyz name];
[self.navigationController pushViewController:_myChildViewController animated:YES];
UIBarButtonItem *_backButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"MyChildViewBackBarButtonItemTitle", #"") style:UIBarButtonItemStyleDone target:nil action:nil];
self.navigationItem.backBarButtonItem = _backButton;
[_backButton release];
[_myChildViewController release];
EDIT 2
I think I may have solved this. I have an UISearchDisplayController added to the view controller nib via Interface Builder.
Originally, I set this to nil when the MyChild controller is sent -viewDidUnload, thinking it is usually enough to set IBOutlet instances to nil in this method. But this doesn't appear to be enough for my search display controller. When I release this in -dealloc I don't get the crash. Is this a bug, I wonder, or expected behavior?
There is a way to find out more about who called (found here):
[...] Also, by the time the app is
terminated due to the uncaught
exception there is no useful
backtrace. If you set a breakpoint on
objc_exception_throw the debugger will
break before the exception is thrown
and you'll have a useful backtrace. I
do this with a .gdbinit file. Create a
file named .gdbinit and place it in
your home directory. This is the
contents of mine:
fb -[NSException raise]
fb -[_NSZombie release]
fb szone_error
fb objc_exception_throw
It's also possible to set these kinds
of breakpoints in the Xcode
breakpoints window or in the debugger
console. [...]
But I assume that won't fix your problem... _existingView seems to be called by the framework when rotating the phone. The only line I can think of telling the framework to perform this on _myChildController is this one:
myChildViewController.managedObjectContext = self.managedObjectContext;
Doesn't it work without this?
_existingView is an internal variable of an UIViewController instance, defined in UIViewController.h
Maybe you are retaining your MyChildViewController someplace in your code.
I was struggling with this too, and the solution was similar to Alex Reynolds'. I release my UISearchDisplayController on -dealloc method, but it had to be before the [super dealloc]. If I release it after super deallocation, it still crashes.