Cannot inspect Self in method while debugging - objective-c

I have a method on one of my ViewController's that is called by one of its view's and delivered some value. It then sends out a message to a manager object with some information about the VC's state.
- (void)elementXChangedWithValue:(float)value {
ParameterManager * pMan = [ParameterManager sharedInstance];
[pMan updateParameter:self.elementX.parameter value:value];
}
In debugging, it was important for me to inspect what the .SomeElement.parameter state was so I could know what was getting lost in translation by the time I get to my ParameterManager.
Unfortunately, although Self is definitely non-nil and accessible the debugger shows scant information about the class making quick and practical glancing of the value difficult. (i will sometimes invoke "po" command in the debugger command line, however).
Not sure if it helps but this project is running heavy with the Objective-C/Swift interoperability although the ViewController is a fully Objective-C class.
Here is an image of what I am getting in the debugger. The drop-down arrow shows nothing but empty.

The debugger isn't perfect and sometimes you just cant see what is in certain areas, such as self. What does always work is NSLog's placed in code though, so if all else fails, add one of those in at the right place to print out the object you wish to know about.

The debugger may show more info after you make it execute these commands:
expr #import UIKit;
expr #import Foundation;
This loads the whole UIKit and Foundation symbols in the debugger at runtime, you only need to execute it once per debug session.
You can automate this with a user-defined breakpoint that'll be triggered every time your application starts in the debugger.
Source : http://furbo.org/2015/05/11/an-import-ant-change-in-xcode/

Related

iOS9 storyboard what is unhandled action (handleNonLaunchSpecificActions)?

I've noticed the following error popping up in the console when running my app on iOS 9 when using a storyboard. I'm using xCode7. Is this something I need to be concerned about?
-[UIApplication _handleNonLaunchSpecificActions:forScene:withTransitionContext:completion:] ** unhandled action -> <FBSSceneSnapshotAction: 0x176bfb20> {
handler = remote;
info = <BSSettings: 0x176a5d90> {
(1) = 5;
};
}
There is nothing wrong with your code. This is a logging message internal to Apple, and you should file a radar about it.
There are two hints that show that this is probably Apple's code:
The underscore leading the method name _handleNonLaunchSpecificActions:forScene:withTransitionContext:completion is a convention indicating that the method is private/internal to the class that it's declared in. (See this comment.)
It's reasonable to guess that the two letter prefix in FBSSceneSnapshotAction is shorthand for FrontBoard, which according to Rene Ritchie in "iOS 9 wish-list: Guest Mode" is part of the whole family of software related to launching apps:
With iOS 8, Apple refactored its system manager, SpringBoard, into several smaller, more focused components. In addition to BackBoard, which was already spun off to handle background tasks, they added Frontboard for foreground tasks. They also added PreBoard to handle the Lock screen under secure, encrypted conditions. [...]
I have no idea what the BS prefix in BSSettings is for, but
BS is shorthand for BackBoard Settings, and an analysis of this log message would indicate that it's not anything you did, and you should file a radar with steps to reproduce the logging message.
If you want to try and grab a stack trace, you can implement the category linked to here. Some would argue that overriding private API is a bad idea, but in this case a temporary injection to grab a stack trace can't be too harmful.
EDIT:
But, we still want to know what this action is. So I put a breakpoint on -[UIApplication _handleNonLaunchSpecificActions:forScene:withTransitionContext:completion] and started printing out register values and found a class called FBSceneImpl which had a whole bunch of information about my application:
We are able to find out which private method is called next (stored in the program counter, instruction pointer, register 15.)
I tried finding the un-handled FBSceneSnapshotAction referenced in the log, but no dice. Then, I subclassed UIApplication, and overrode _handleNonLaunchSpecificActions:forScene:withTransitionContext:completion. Now I was able to get at the action directly, but still, we don't know what it is.
Then, I looked at the FBSceneSnapshotAction again. Turns out it has a superclass called BSAction.
Then I wrote a tool similar to RuntimeBrowser and looked up all of the subclasses of BSAction. It turns out that there's quite a list of them:
The two method names we have (one from the log and one from the program counter on the devices) indicate that these actions are used under the hood for passing actions around the system.
Some actions are probably sent up to the app delegate's callbacks, while others are handled internally.
What's happening here is that there is an action that wasn't handled correctly and the system is noting it. We weren't supposed to see it, apparently.
AFAIK, the info above is related to iOS during snapshot the screen (i suppose for double click home multitask related behaviour).I deeply investigated my application and seems that it does not get any side behaviours. You can safely ignore it, for now.
You can use the following gist simple category to test yourself against the calls to the above function:
I have figured it out, it will happen when you have IBAction method declared in .h or .m file but you have not bind it to any control.
.m example:
- (IBAction)click:(id)sender{
}
but not assigned this method to any control in storyboard.
haven't find out why it happens in my app, but at least you can catch the exception, if you want to keep this from popping up in your log pane. It's not a solution, but it might give you more insight why it is happing by inspecting any of the arguments that are passed in the catch.
swift 2 version:
import UIKit
extension UIApplication {
func _handleNonLaunchSpecificActions(arg1: AnyObject, forScene arg2: AnyObject, withTransitionContext arg3: AnyObject, completion completionHandler: () -> Void) {
//whatever you want to do in this catch
print("handleNonLaunchSpecificActions catched")
}
}

Xcode: "Spurious Update" console warning?

I'm writing a pretty straightforward ObjC app. (The only minor complexity is that it uses an external library called Chilkat for some basic networking, but I don't think that that's relevant.)
Occasionally, my project spontaneously pops up this warning message:
May 14 01:24:01 Neovenator-2.local Project[22645] : void
CGSUpdateManager::log() const: conn 0x4b29b: spurious update.
And I have no idea how to handle or even interpret it. There's nothing in my project called CGSUpdateManager, and my project doesn't call a log() function anywhere. I can't even reliably reproduce it, but it's popped up often enough to raise my interest level.
Searches at both Google and here for the term "spurious update" reveals a lightly scattered set of conversation, but nothing relevant to my project. Meanwhile, a Google search for "CGSUpdateManager" reveals it's something to do with Swift, which I'm not using at all.
Can anyone help me understand what this means? Or should I just disregard it?
Make sure to call super in viewDidLoad, viewWillAppear and viewWillDisappear.
Sorry, my code with correct Highlight/indentation:
- (void)setNeedsDisplay
{
//#if 1 //TEST (suppose we are only called by us)
if(wvImageRep_DoRebuild)
//#endif
[super setNeedsDisplay]; // "spurious update" ?
}
It's an example (#see my full response), it helped me

xCode: Accessing properties of an object via console

Is it possible to access the properties of objects in xCode console?
If I try the following I get an error that he property doesn't exist.
po someObject.someprop
If I don't breakpoint the code and run the app it works fine so I know someObject.someprop exists. I don't think I have the grasp on xCode console yet? What I loved about Flex/Flash development is that I could set a break point and in the console window or variables view I could traverse every structure down to the ends of the earth.
I could see SomeDicionary[key].someArray[1].someObject.prop and it would show me the value. Is this not possible in xCode console or is there a trick to get to it?
You'll actually have to use the bracket syntax notation:
po [someObject someprop]
The debugger is sometimes very finnicky about syntax. This is filled with all sorts of helpful tips for debugging in XCode.
Just a side note, variables/properties declared in the implementation file (*.m) instead of the header file (*.h) can sometimes be invisible to the debugger variable list display depending on if the breakpoint is in that class's code, because of scope. Not necessarily required here, but useful to know seeing as how it is kind of relevant.

Xcode 4.3 Breakpoint Logging object descriptions

I'd like to move from NSLogging all over the place to using breakpoints for logging where the performance hit doesn't preclude it.
I know I can just po an object with a Debugger Command action, and I know I can just log any string by choosign the Log Message action.
And I think I should be able to combine both by choosing Log Message and entering something like SomeText giving context for object description: #(const char *)[[anObject description] UTF8String]#. Unfortunately, this doesn't seem to work, and always gives me what I assume to be the pointer to the description string.
What am I doing wrong?
It's kinda tricky but I think that this will work. Set the breakpoint Action as a debugger command. Then use this text as the action:
po (NSString *) [#"Some text describing: " stringByAppendingString:(NSString *)[anObject description]]
You must always be very careful to cast return types when working in the debugger. Both with GDB and LLDB.
I like your idea of using breakpoints to avoid the performance hit, but this also means that your logs will only be printed when connected to a debugger. While NSLogs will buffer their output to the system log, viewable from the Organizer (Devices) in Xcode.
(Edit: I missed the question's point and it's not an answer)
I think it's best to use DebugLog. It's a macro, and you can disable it easily (it's on when you def-ine DEBUG in your debug builds and is off when you don't define it). So, there's no performance degradation (quite the contrary).
Simply replace
NSLog(#"Hello, World!");
with
DebugLog(#"Hello, World!");
And instead of
19/4/12 8:55:52.949 PM Dictionary: Hello, World!
You'll get:
BetterDictionary.m:737 Hello, World!
(it shows which file and even which line has logged it)
Which is infinitely more interesting. undefine DEBUG for your production build and DebugLog won't be called at all.
And don't forget to #import 'DebugLog.h'.

EXC_BAD_ACCESS on animationForKey:

I'm trying to use a recent feature of the Scintilla component, which provides OSX-like text-highlighting effect (the yellow animated bouncing box), and I'm stuck with an error that pops up intermittently :
EXC_BAD_ACCESS
pointing to this particular line :
if (layerFindIndicator!=nil)
if ([layerFindIndicator animationForKey:#"animateFound"])
[layerFindIndicator removeAnimationForKey:#"animateFound"];
(the ifs are mine; just in case I caught the object layerFindIndicator being nil, or deallocated or whatever... Unfortunately, it doesn't help...)
layerFindIndicator is seemingly a subclass of CAGradientLayer. (You may see the full code for layerFindIndicator, here).
Since, I'm an absolute newbie to Quartz Core, could please give me any hint as to HOW this could be debugged?
Since, I'm an absolute newbie to Quartz Core, could please give me any hint as to HOW this could be debugged?
This doesn't have anything to do with QuartzCore specifically (at least, I hope not)—it's general this-object-has-been-killed-before-its-time-how-do-I-find-the-killer stuff.
In Xcode:
Edit your current scheme.
For the Profile action, set it to use the Debug build configuration.
Dismiss that and then hit the Profile command.
Xcode will build for that action and then launch Instruments.
Instruments will prompt you to choose a template; you want the Zombies template. Once you've chosen it, Instruments will create a trace document and run your application. Switch to your application (if it isn't already frontmost), then do whatever causes the crash.
If the crash really is a dead-object crash, Zombies will reveal it. You'll get a flag in Instruments's timeline saying something like “message sent to zombie object 0xd3c2b1a0”, and your program will probably exit shortly thereafter.
In that flag is a tiny little button that looks like this: ➲ except it'll be gray. Click on it.
That takes you to the history of that object (actually of that address, including any previous objects or other allocations that have started at that address). Show your Extended Detail Pane (the one that appears on the right showing a stack trace), then scroll down to the end and then move backward (upward) step by step through time, looking at releases and autoreleases, looking for the one that isn't balancing out the object's allocation or a retain.
The solution will probably involve one or more of:
Changing a property to be strong or weak rather than assign/unsafe_unretained
Adding a property where you previously did not strongly own an object
Rearchitecting some things, if it's not clear which of the above you need to do or if either one of them seems like a filthy hack
Switching to ARC to get weak properties and __weak instance variables (both of which get set to nil automatically when the referenced object dies) and to get local variables being implicitly initialized to nil
But it'll depend on what you find in Instruments. And, of course, there's the chance that your problem—the bad access—isn't a dead object at all and all of the above will not help you.
Try this:
if (layerFindIndicator!=nil){
if ([layerFindIndicator animationForKey:#"animateFound"]){
[layerFindIndicator removeAnimationForKey:#"animateFound"];
}
}
Also check to see if it is released else were.
EDIT:
Another thing I found was you didn't have an white space in the if. Your code should now look like this:
if (layerFindIndicator != nil){
if ([layerFindIndicator animationForKey:#"animateFound"]){
[layerFindIndicator removeAnimationForKey:#"animateFound"];
}
}