Crash upon text selection and deletion from menu in UITextView - cocoa-touch

My UITextViews crash the app upon text selection and deletion.
Cut, copy, and paste seem to work fine. The only error in the log is:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIMenuController view]: unrecognized selector sent to instance 0xff85ac0'
It is a normal UITextView, and the UIMenuController is untouched and uncustomized. Any ideas?
Happens with iOS 4.3 and 5.0 in simulator and on device.
No more information with zombies enabled, except for a stack trace that I'll need to interpret.. The new Xcode isn't nice about this:
(0x356338bf 0x360ae1e5 0x35636acb 0x35635945 0x35590680 0x37c63925 0x3816b 0x1a557 0x3559222b 0x37a869a7 0x3559222b 0x31671943 0x35607a63 0x356076c9 0x3560629f 0x355894dd 0x355893a5 0x32073fed 0x3794d743 0x29d1 0x2990)

The cause was undocumented (correct me if you find documentation and I'll update this answer) behavior from UITextView and UITextField with their default use of UIMenuController. The "Delete" option is added if your UIText*Delegate implements delete:. When "Delete" is selected from the menu, your field's delegate will then be called with a delete: message. I discovered this by adding an exception breakpoint in the breakpoint listing pane, which gave me the properly symbolicated stack trace that the original exception did not. The crash was caused because I was using delete:(id)sender to service bar button items in a way that required use of the sender. I fixed it by renaming delete: to deletePart:. The user can still delete text by selecting "Cut".

Having view sent to UIMenuController means that you probably assigned the UIMenuController somewhere it shouldn't go. See if you set anything to equal menuController (or whatever your instance variable name is) and see if that causes an issue.
Also, this could be an overrelease happening much earlier in the code where the UIMenuController just happens to allocate in the memory space that was formerly occupied by something that was released too early. Enable NSZombies and see what your error changes to.

Related

Why does an object with a retain count of 0 respond to a message?

With ARC turned off:
I create an instance of my custom class using alloc, so it has retain count of 1.
On the next line, I NSLog() the instance (I implemented a description method in my custom class).
On the next line, I release the object.
On the next line, I NSLog() the instance again, i.e. I send it a description message, and I see the same output in the console. I expected some kind of error output.
Here is the relevant code:
AppDelegate.m:
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
Greeter* host = [[Greeter alloc] initWithName:#"Maggie"]; //My custom class
NSLog(#"Greeter %#", host);
[host release];
NSLog(#"Greeter %#", host); //Create error: send a `description` message to an object whose retain count is 0.
return YES;
}
...
...
Greeter.m:
...
- (NSString*)description {
return [
[[NSString alloc] initWithFormat:#"\n\tname: %# \n\tCreated on %#", [self name], [self today]]
autorelease
];
}
--output in Console:--
2015-04-26 21:18:58.914 Flashlight[2380:62826] Greeter
name: Maggie
Created on 2015-04-27 03:18:58 +0000
2015-04-26 21:18:58.915 Flashlight[2380:62826] Greeter
name: Maggie
Created on 2015-04-27 03:18:58 +0000
Similar code in cocoa, causes weird stuff to happen, and Xcode flags the second NSLog() with EXC_BAD_ACCESS.
Response to comments:
I decided to start a new app to try some things, and here is what I discovered:
In Xcode 6.2, even though there is no error in the console, i.e. both NSLog()'s print the same thing, Product>Analyze will point out the line with the error saying: Reference-counted object is used after it is released. And if I click on that message, Xcode shows a nice graphical explanation of how that happened in the code.
If I edit the scheme to enable Zombie objects, then instead of the second NSLog() message, I get an error message:
Flashlight3[606:11093] *** -[Greeter respondsToSelector:]: message
sent to deallocated instance 0x7fb5e1caa8c0
After poking around in Xcode for much too long, I figured out how to edit the scheme. To the right of the Run and Stop buttons, there is a jump bar showing: ProjectName>Platform, which in my case is Flashlight>iPhone6. I clicked on Flashlight, and a drop down list displayed Edit scheme. I clicked on Edit scheme, then under Run/Debug, there is a checkbox for Enable Zombie Objects, which I checked.
Did you compile with debug symbols?
I guess not. I read some Apple docs to figure out how to do that: I clicked on the top line in the Project Navigator, chose Build Settings, then I scrolled down to Build Options, then I selected Build Variants, then I clicked the arrow to reveal Debug and Release. To the right of Debug, I clicked on normal, and I typed in debug.
I'm not sure what that does. I see no difference after doing that.
Do you find your code in the stack trace?
In the Stack Trace area:
Product>Profile
Scroll down the window and choose Zombies.
Then click the red Record button.
A Zombie Messaged popup will appear.
Inside the popup, click the arrow with the gray circle around it.
In the bottom pane, click on the Zombie line.
In the bottom right pane, at the top of pane, select the icon on the far right.
...there are a bunch of names in a list preceded by an icon:
Some of the icons are black. If I click on enough of the black icons, I eventually jump to my code. Doing that is problematic, though, because when I click on one of the black icons, it is hard to get back to the Stack Trace list to try another black icon. Edit: Okay, I found a way to get around that problem: when I click on one of the icons in the Stack Trace pane, it takes me to some code where one of the lines will have a red arrow pointing at it. If I click on the red arrow, it will show me a popup containing the Stack Trace list, and then I can click on one of the other black icons.
Just because an object's retain count goes to 0 and its dealloc method is called, doesn't mean the memory used by the object is instantly turned to garbage. The deallocated object could possibly sit in memory, intact, for a while before the memory space is reused for something else.
That seems to be the case here. The call to log host after it's been deallocated finds that the memory for the deallocated object is still intact so accessing its data works.
But it seems in your test on a Mac results in the memory being handled differently causing the exception.
rmaddy's answer is completely correct. But likely you want to know, how to get an error message in such a case.
There are two options:
Run the static analyzer. It can detect some of these errors.
Enable the zombie option in the scheme. This will keep the instance objects alive and report an error message, if they are used.

iOS - mysterious SIGABRT

I'm getting a SIGABRT - any suggestions how I catch it?
The only clues I have so far are:
the Exception breakpoint (How to track down cause of SIGABRT) does not seem to be catching it
it only crashes on the iPhone 4 device running iOS7 and not on the iPhone 4s simulator or the iPhone 6 device.
Here's my (pretty useless) stack trace:
UPDATE
A longer (but no less useless) stack trace:
Look in the console log. It will provide some info on the error which caused sigabrt. Also be sure to check your outlet and action connections. You may have deleted a outlet after you linked it up and that way xcode can't find that missing outlet you deleted.
SIGABRT occurs when you accidentally/intentionally change connections of an outlet or an action.
According to you, you deleted a connection by merely deleting it from the code but under the hood, it still exists.
So, what you can do is, click on the attribute which is giving the sigabrt and then click on the connections inspector on the right side of the Xcode.
If you see any stray connections, just delete it. This is how you actually delete a connection.
Hope this helps.

popping to UIViewController causing crash - message sent to deallocated instance

I have a UIViewController I am showing as a Modal popover. When that view is done being used I am popping to a particular location in my UINavigationBar:
[[appDelegate.homeViewController navigationController] popToViewController:[[appDelegate.homeViewController navigationController ].viewControllers objectAtIndex:2] animated:YES];
The View Controller presenting the modal UIViewController is mentioned in the crash below:
*** -[ClientDetailsViewController respondsToSelector:]: message sent to deallocated instance 0x8c17650
How can I track this down and see what is causing my crash?
How can I track this down and see what is causing my crash?
Simply activate Zombies.
In Xcode4, hold the alt key while choosing "Product" > "Run" from the menu to show the Schemes dialog (or choose Edit Schemes to show it).
Then in the "Diagnostics" tab, check the "Enable Zombie Objects" checkbox
Now when an object is used after it has been deallocated, you will be able to see which object is concerned and when it has been over-released.
Moreover, don't hesitate to use the static analyzer from the "Product" -> "Analyze" menu so that Xcode will tell you every memory management errors (and others) he can find in your code.
You should always run this "Analyze" tool once in a while and fix ALL the warnings it displays, as it is a very good tool to tell you what may be wrong in your code and is of very good advice.
Not having any warning when you run this tool is not a guarantee that your code won't crash, but having warnings when you run this tool quite guarantee you the're something to be fixed in your code.

program received signal EXC_BAD_ACCESS in Xcode

When I am trying to add the tableview in xcode when I click the table item then it goes to the next screen and again when i click the back button and go to previous tableview page and select the table item then it gives the error as program received signal EXC_BAD_ACCESS
It's a memory issue
it happens when you trying to access an object which is already being released.
EXC_BAD_ACCESS indicate memory issue, you may release object already been released, try enable NSZombie for further information, add NSZombieEnabled to the "Environment Variables" section in scheme settings.

NSZombieEnabled isn't helping my obj_msgSend

I'm getting an EXC_BAD_ACCESS with my iPhone app on 0x01ad809b <+0015> mov 0x8(%edx),%edi
I have NSZombieEnabled set to YES but I'm not seeing any class printed out in the debugger like I normally do.
Is there another way to debug this problem?
You have a crash caused, most likely, by corruption of memory, using a variable that isn't initialized, and/or casting a non-object type to an object.
First, post the backtrace of the crash. That will provide more context.
Second, try Build and Analyze. Fix any of the problems that it identifies.
Finally, if this is a new crash, go back to a revision right before the crash and then roll forward until you hit the crash. What are the changes made over that span of time?
With more context -- the crash log, in particular (or backtrace, at the least) -- more specific debugging techniques can be offered.
You can select Breakpoint navigator and add breakpoint on all exceptions. Maybe it will help.
Try with malloc info as well.
Use Instruments to Profile and detect zombies instead.
Change the build target to the Simulator
In the Build menu, select Profile
Instruments will open, then select the Zombies instrument
This automatically sets up the NSZombieEnabled flag and will popup a message whenever a dealloced object is messaged. Clicking the disclosure will show the memory management events of the object.