Things like this drive me crazy when debugging:
(lldb) p self.bounds
error: unsupported expression with unknown type
error: unsupported expression with unknown type
error: 2 errors parsing expression
(lldb) p (CGRect)self.bounds
error: unsupported expression with unknown type
error: unsupported expression with unknown type
error: C-style cast from '<unknown type>' to 'CGRect' is not allowed
error: 3 errors parsing expression
(lldb) p [self bounds]
error: 'bounds' has unknown return type; cast the call to its declared return type
error: 1 errors parsing expression
(lldb) p (CGRect)[self bounds]
(CGRect) $1 = origin=(x=0, y=0) size=(width=320, height=238)
(lldb) You suck!
error: 'You' is not a valid command.
(lldb) …
Why did the first 3 attempts fail? Is there any simpler way to print self.bounds? Thanks.
You can access it by
p (CGRect)[view bounds]
or
p view.layer.bounds
view.bounds is actually view.layer.bounds
It seems that the type info of [UIView bounds] is not available to lldb
Starting from Xcode 6.3, we have a better solution. In short, you need to import UIKit for LLDB to know about these types:
expr #import UIKit. Check out this article to learn some tricks to make your life even easier.
You gonna love Xcode 6.3+
TLDR
(lldb) e #import UIKit
(lldb) po self.view.bounds
LLDB's Objective-C expression parser can now import modules. Any
subsequent expression can rely on function and method prototypes
defined in the module:
(lldb) p #import Foundation
(lldb) p NSPointFromString(#"{10.0, 20.0}");
(NSPoint) $1 = (x = 10, y = 20)
Before Xcode 6.3, methods and functions without debug information
required explicit typecasts to specify their return type. Importing
modules allows a developer to avoid the more labor-intensive process
of determining and specifying this information manually:
(lldb) p NSPointFromString(#"{10.0, 20.0}");
error: 'NSPointFromString' has unknown return type; cast the call to its declared return type
error: 1 errors parsing expression
(lldb) p (NSPoint)NSPointFromString(#"{10.0, 20.0}”);
(NSPoint) $0 = (x = 10, y = 20)
Other benefits of importing modules include better error messages,
access to variadic functions when running on 64-bit devices, and
eliminating potentially incorrect inferred argument types.
PS: If you also confuse p vs po
p == print == expression -- == e --
po == expression -O -- == e -O --
-- is the separator between command+flag vs inputs
-O flag is for invoking the object description method
With Xcode 6.3, we can import UIKit and then print the frame or bound of view
expr #import UIKit
p self.view.bounds
LLDB does not support dot notation for message sending when using p and that's why
p self.bounds
doesn't work, but
p [self bounds]
does.
(It actually supports it for objects when you use po, though)
Also, LLDB doesn't have type information of non-objects available at runtime, so you need to explicitly provide a type by casting the return value.
I don't know what was the context when you running this. But looks like lldb cannot find the type of self.
In order for lldb to evaluate self.bounds, it need to know the type of self is some Class has property bounds. It cannot assume self is ObjC type because you may call it under such context:
void test()
{
struct
{
int bounds;
} self;
}
so you get the error error: unsupported expression with unknown type
However, if you call it using [self bounds], lldb knows that self much be ObjC type because [] syntax only apply to ObjC type. But since the type of self is not clear, it still cannot evaluate the result of [self bounds] so you need to cast it to CGRect
Try with following expression,
p self.view.bounds.size.width
or use,
po self.view
p - Print is only uses to print normal/simple values
while,
po - Print Object works same as NSLog to print value of an object
I tried #an0's answer expr #import UIKit, but it didn't work.
Then I added a pch file, and add these lines of code in the file:
#ifndef PrefixHeader_pch
#define PrefixHeader_pch
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#endif
#endif /* PrefixHeader_pch */
Next, link the pch file to my project:
Run the app again, then I can use the dot notation in lldb console:
(lldb) po self.view.bounds
For how to add a pch file , see the answer here PCH File in Xcode 6
Related
I am seeing this currently
expr self.attributedText = [(NSAttributedString *)([NSAttributedString alloc]) initWithString:#""];
error: <user expression 24>:1:75: no known method '-initWithString:'; cast the message send to the method's return type
self.attributedText = [(NSAttributedString *)([NSAttributedString alloc]) initWithString:#""];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
While creating a NSString works:
(lldb) expr str = [(NSString *)([NSString alloc]) init];
(__NSCFConstantString *) $92 = 0x00007fff8098cd68 #""
just telling NSAttributedString is not an Extension of/or inherited from NSString, instead it has a property called string
and if you can avoid the paranthesis if you do not need a cast.
(lldp) expr str = [[NSAttributedString alloc] initWithString:#""];
should just work
You can usually avoid the need to cast Foundation methods like this in the expression parser by importing the Foundation module in the debugger.
If you build your code by using the "modules import" form:
import Foundation;
and passing -fmodules when building the .o file (there's also an Xcode setting for this) then the debug info records that your code imported the Foundation module, and lldb will automatically import that.
If you don't use the module form, you can still get lldb to import the module by doing:
(lldb) expr #import Foundation
Doing either of those things, I can run your expression w/o extra casting.
In xCode when i debug using po i get this error.
(lldb) po [NSString stringWithFormat:#"tel:%#",item.CNUMBER]
error: too many arguments to method call, expected 1, have 2
Some questions that i looked at but doesnt help me.
Too many arguments to method call expected 1, have 2
Too many arguments to method call
Too many arguments to method call, expected 1, have 2?(Xcode)
I even had a moment where i questioned my sanity and went to apples documentions. https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Strings/Articles/FormatStrings.html
[NSString stringWithFormat:#"Long %C dash", 0x2014]; // from apples doc
and the results are the same...
(lldb) po [NSString stringWithFormat:#"Long %C dash", 0x2014];
error: too many arguments to method call, expected 1, have 2
im using macOS 10.12.4 and xCode 8.3.2. I even reinstalled xCode from scratch. Any ideas what can be causing this!?
e: using po item.CNUMBER gives me the phone number like its supposed to
item is just a model i use to parse a json response, no methods involved.
LeasesModel *item; // declared as an instance var
...
#interface LeasesModel : NSObject
#property(nonatomic, strong) NSString *ID, *PROPERTYNAME, *ADDRESS1, *ADDRESS2, *CITY, *STATE, *ZIP, *WBPOINT, *COMMENTS, *CNAME, *CNUMBER, *CEMAIL, *CCOMPANY, *ISRETAILSPACE, *ISOFFICESPACE, *ISCOMMUNITYFACILITY, *SQFT, *STATUS, *ASKINGRENT, *FLOORCOUNT, *FLOOR1SF, *FLOOR1ASKING, *FLOOR2SF, *FLOOR2ASKING, *FLOOR3SF, *FLOOR3ASKING, *FLOOR4SF, *FLOOR4ASKING, *FLOOR5SF, *FLOOR5ASKING;
#end
e: i was unable to reproduce the error in a new project.
Thanks to #danh, we figured out the issue with was a NSString extension method. Removing it allowed me to debug like normal.
It seems that the default behavior in XCode is to silently allow redefinition of local variables if they are declared in a deeper scope, but throw an error or warning otherwise. For example, XCode produces an error for "Redefinition of 'var'" if it is redefined in the exact same scope:
- (void) doStuff
{
NSString *var = #"Hello World";
NSString *var = #"Goodbye"; // Error on this line
}
Similarly, if I have an ivar called 'var', and I try to re-declare 'var' in a local method, XCode will produce a warning for "Local declaration of 'var' hides instance variable" when I try to use it:
//MyClass.h
...
#interface MyClass : NSObject
{
NSString *var;
}
...
//MyClass.m
...
- (void) doStuff
{
NSString *var = #"Hello World";
NSLog(#"%#",var); // Warning thrown on this line
}
So far this is what I would expect. However, if var is redefined in a deeper scope, such as an if block or for loop, XCode allows it, and the outer declaration is silently ignored:
NSString *var = #"Hello World";
if (TRUE)
{
int var = 0;
NSLog(#"%d",var); //prints '0', No errors or warnings
}
NSLog(#"%#",var); //prints 'Hello World'
Why is the last example silently allowed, but the other two are caught? Is there some option or flag I can toggle in XCode so that an error or warning would also be created in the last example? If XCode won't catch it for me, is there some code I could write to make sure variables are never redefined? Or is it just my responsibility to make sure I'm not re-using my variable names?
In the build settings (Xcode 5 & 6, at least) you can set a warning for Hidden Local Variables to YES.
The last example is behavior that Objective-C inherits from standard C. A variable's scope is determined by the bracing level. It's been that way since the earliest days for C. It's called variable shadowing, and it's actually pretty useful in ensuring that code keeps working even in the face of API changes in system libraries.
As far as why it's allowed, but the earlier examples aren't, that's a consequence of how Objective-C implements instance variables. The instance variables are essentially treated as local variables of each of the class's methods. So when you declare a local variable in a function that shadows an instance variable, it gets flagged as an error. Basically the first and second cases are treated as equivalent.
To get a warning for these cases, set the LLVM warning option Hidden Local variables to Yes.
I am trying to set a BOOL within Xcode and for some reason it is plain refusing to work. Nothing else is setting this bool, just this one instance. My code is below:
.h
#interface SuspectsViewController : UIViewController
{
BOOL boolContentChanged;
}
#property (nonatomic) BOOL boolContentChanged;
.m
#synthesize boolContentChanged;
-(IBAction)buttonPressed:(id)sender
{
boolContentChanged = true;
}
I have also tried using self.boolContentChanged but nothing happens either. To try and debug this I used po boolContentChanged and get the following output, the first po is before boolContentChanged = true and the second is after.
(lldb) po boolContentChanged
(BOOL) $4 = '\0' <nil>
(lldb) po boolContentChanged
(BOOL) $7 = '\0' <nil>
Does the $ indicate that it's pointing to a certain address, or is that purely for debugging reference?
Also, is there any reason this would be nil? Surely it doesn't need implicitly setting if it is a bool and not a pointer?
Any advice on this is much appreciated as I can't work it out,
Thanks in advanced,
Elliott
"po" in the debugger (gdb) is short for "print-object". The BOOL type is not an Objective-C object. Use "p" or "print" to display the value of BOOL, int, char, etc.
The dollar-number ("$4") output by the debugger in response to your "po" command is assigning the result to a variable in the debugger which you can use in later commands.
As to the problem you describe, can you confirm that your action method is actually getting invoked? Try adding:
NSLog( #"In %#", NSStringFromSelector( _cmd ));
to your -buttonPressed method. If your action is actually getting invoked, you'll see this in the debugger:
In buttonPressed:
You can also have the NSLog() output the values of your BOOL:
NSLog( #"Before: %d", (int)boolContentChanged );
I finally managed to figure out what was happening. In regards to the debugger it did make a practical difference using YES / NO as opposed to true / false, the values were still being set if I used p to explicitly find them, but when using YES / NO they would show automatically. So once again it seems to be the intellisense that is failing to update in certain situations.
Thanks for the help all.
When you use BOOL you need to use YES or NO not true and false.
I am refactoring to use ARC in my project and can not figure out this problem for the life of me!
I don't know where I got the code from.
screenshot of error http://img341.imageshack.us/img341/972/xcode.png"screenshot of error"
http://img341.imageshack.us/img341/972/xcode.png
The problem is that you are not using bridged casting. You have to use bridging to cast between C types and Objective-C types:
[UIView beginAnimations:#"earthquake" context:(__bridge void *)itemView];
When casting from a C pointer type to an Objective-C type:
UIView * item = (__bridge UIView *)context;