I am using xCode 4.3.1 and as soon I want to use lldb, I hardly get any debug information but get the following result instead, po-ing on a simple NSMutableDictionary property:
(lldb) po _keywordCache
error: instance method 'delegate' has incompatible result types in different translation units ('objc_object *' vs. 'id')
error: instance method 'delegate' has incompatible result types in different translation units ('objc_object *' vs. 'id')
note: instance method 'delegate' also declared here
note: declared here with type 'id'
note: instance method 'delegate' also declared here
note: declared here with type 'id'
error: 2 errors parsing expression
Switching to gdb always gives proper results.
Anyone an idea?
The source of the problem in my case was that the property in question here, "delegate" is declared as a subtly different type in the instance variable and the property declaration. In my case, the instance variable type was id and the property declaration was id<SomeProtocol>.
I'm going to report this as a bug to Apple, as it shouldn't cause failure to inspect variables. The fix is to make sure that the instance variable and the property declaration describe "delegate" as exactly the same type. Hope this helps!
I know this is late, but ran into this on Xcode 6, needed to do a Clean Build Folder (hold down option while selecting clean).
I have the same problem in Xcode 7.3 (7D1002) since yesterday. Before it worked fine for weeks. In my case now even a simple "po someString" doesn't work:
error: instance method 'URLEncodedString' has incompatible result types in different translation units ('void *' vs. 'NSString *')
error: instance method 'URLDecodedString' has incompatible result types in different translation units ('void *' vs. 'NSString *')
note: instance method 'URLEncodedString' also declared here
note: instance method 'URLDecodedString' also declared here
error: 2 errors parsing expression
Things I tried:
quit and relaunch Xcode7 and the simulator (they were both running since several days without relaunch)
Xcode:Product->Clean and (holding the option key) Clean build folder
Delete ~/Library/Preferences/com.apple.dt.Xcode.plist
Delete ~/Library/Developer/Xcode/DerivedData/*
Delete ~/Library/Developer/Xcode/iOS DeviceSupport/*
Install the latest OS X El Capitan Update 10.11.4
but all that didn’t help. Still can neither p nor po strings in the debugger.
I still have an old Xcode 6 on my Mac (renamed and put away before installation of Xcode 7, then put back in /Applications). And that still works, I can enter “po someString” in the debugger and it prints the string into the debug log. But Xcode 7 doesn´t…
I found a workaround for local variables (even though this problem is different) here:
http://lists.apple.com/archives/xcode-users/2014/May/msg00088.html
ctrl-click on variable in local variables list and choose “print description”
Printing description of someString:
ipad
which helps a little but cannot print more complex commands.
I also had that error, for me it actually had nothing wrong with the code though. All i did was click the button on the right of the "Toggle global breakpoint state" button in the console.
It is the blue, arrow-shaped button.
Related
the Code: [NSClassFromString(#"Test") gotoTest];
usage ARC with Error: No known class method for selector 'gotoTest'
but in MRC warning no error.
Way ARC from warning becomes an error ? do you have any reference? I want to know the essential reason.
You did not include the warning under MRC:
Class method '+gotoTest' not found (return type defaults to 'id')
and this contains a vital clue – the compiler is looking for the return type. Under MRC it assumes id and will let you assign the result as an object reference. If you mess up and the return type is, say, float, things will probably go wrong.
Under ARC it is the compilers job to do the memory management of any returned value, and to do this correctly it needs to the the type. So if it can't determine the return type it produce an error.
Your code fragment suggests you know the selector takes no arguments and returns no value, so declare it as such. If you've no class with the method you can use a protocol, something like:
#protocol GotoTest
+ (void) gotoTest;
#end
will do. Now the compiler knows the types and your code will compile under ARC.
HTH
With code like this:
- (nonnull NSString *)testing {
return nil;
}
Shouldn't I get a compiler warning? I get no warning all, which seems to make the entire nullability stuff seem useless?
Well, in my opinion it should produce a warning, but I couldn't figure out to get one either.
What might be helpful though, is using Product > Analyze to run the CLANG Static Analyzer. This should give the following hint:
Null is returned from a method that is expected to return a non-null value
Another thing worth mentioning is the setting CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION which is named Incorrect Uses of Nullable values in the Apple LLVM 7.1 - Warnings - All languages section of the Build Settings.
This setting will not produce a warning for incorrect return values, but it shows a warning when using the method with incorrect parameters (e.g. nil for nonnull parameters).
This answer refers to Xcode Version 7.3.1 (7D1014)
"nonnull" is mostly there to combine Objective-C and Swift. Swift will translate the type of the method to "NSString" and not "NSString?".
I'm facing big issues when trying to print out Objective C properties in many situations when I'm almost certainly sure it SHOULD work.
Consider the following setup:
The view controller's property has strictly set class (Card *), but still, LLDB outputs an parsing error where subproperty cannot be found on object of type id.
Having an object property defined on a view controller (see points 5 & 6):
stop at breakpoint inside the controller code (f.e. in -viewDidAppear: method)
try to print out the property itself with po _card (points 1 & 2)
try to print out its subproperty with po _card.offlineURL (points 3 & 4)
an LLDB parsing error occurs
Printing out via [_card offlineURL] prints out proper object description as LLDB sends a message to Card object with no class check.
Definition of object property on the controller declares non-id class, though (point 5).
I'm expecting LLDB to print out the property object's subproperty description, NSString containing URL string in this case, but this annoying LLDB error occurs instead.
This is just a single example from many. Sometimes it affects direct property printout, numbers printing etc. These issues are way more frequent since integration of Swift began, being worse with every new version of Xcode since 6.2, including the latest 7.2.
This happens in my Objective C project in many situations, though sometimes it works fine in different cases.
Do you know about any work-arounds or fixes for this issue? I've already filed a report on Apple Bug Reporter, but this will certainly take time for Apple to even notice.
The most likely problem given the info in your question is that we don't actually have debug information for _card.
The lldb command:
(lldb) image lookup -t Card
will tell you whether lldb had debug information for Card available to it. If this doesn't find anything, then maybe some part of your project isn't getting built with debug info. If the command does find some correct definition of Card, then it must be that the debug info for the _card ivar is not getting hooked up to this type correctly.
If there is a definition of Card, then the workaround:
(lldb) po ((Card *) _card).offLineURL
is available.
For future reference, there are two other bits of behavior that are probably complicating your attempt to figure out what is going on here:
1) (w.r.t. picture 3) The Xcode IDE uses its built-in indexer for auto completion in the debug window as well as the Source Code editor. But the debugger runs off debug information, since we need to be able to debug things that aren't built in Xcode. So the fact that auto-completion can find a name in an expression doesn't tell you anything about what lldb will do.
2) (w.r.t. picture 2) po force-casts the expression you are trying to "po" to an ObjC object (i.e. "id") and then calls its description method. The description method of an ObjC object that doesn't override description prints the type name and the address. So lldb didn't need to know the type of the _card ivar to get the output you saw. We only start to need types when the expression is more complex and involves accesses to ivars or properties of an ObjC object in the expression.
Note also, by default if you do:
(lldb) print _card
lldb will evaluate the expression "_card", find it resolves to a pointer of at least type id, then follow that pointer's isa pointer into the ObjC runtime to figure out what the dynamic type is. So it is likely to print Card * in this case.
But the expression parser hasn't yet been taught to resolve the dynamic type of sub-expressions within the expression parser in mid-parse. That would actually be quite a trick... So if it doesn't know the full type of _card, then:
(lldb) print _card.offlineURL
isn't going to work, since id does indeed not have a property of that name.
You can work around this by doing:
(lldb) print _card
$0 = (Card *) 0x12345678
Then:
(lldb) print $0.offlineURL
since the result variable captures the full dynamic type information, that will also be available in subsequent expressions.
I am trying to debug my iOS app using lldb and I'm getting really weird errors on debug.
A few lines before my breakpoint, I've got:
CGRect frame = view.frame;
Which I can access with no problems with print frame command in lldb. However, when I try to access the frame again in lldb, I type print view.frame and get the following error:
error: property 'frame' not found on object of type 'UIView *'
This doesn't make sense as I can verify the view is a UIView* instance and has a valid property called frame by typing po view and getting correct results:
(UIView *) $4 = 0x1e199bf0 <MyAppCustomView: 0x1e199bf0; frame = (3398 3396; 204 208); layer = <CALayer: 0x1e199ce0>>
This particular lldb error happens to me a lot, and I couldn't find the cause of this error. Someone suggested at Property 'count' not found on object of type 'NSMutableArray *' PO command in lldb that one could use gdb as (gdb) p view.frame but I'm getting error: '(gdb)' is not a valid command. and I highly suspect that a gdb command would "work?" inside another debugger anyway.
Any suggestions or workarounds for this bug which occurs randomly?
Dot notation for message sending is not supported in lldb when using Objective-C. Use bracket notation and cast the result to CGRect:
p (CGRect)[view frame]
Just in case the above doesn't work (which it didn't for me, looking for the frame for a variable cell, class derived from UITableViewCell): forcing the extra parentheses seemed to help lldb's little ditty brain:
p ((CGRect)[cell frame])
presto magico:
(CGRect) $5 = origin=(x=0, y=0) size=(width=320, height=44)
I had to disable (uncheck) Thread Sanitizer in Xcode > Product > Scheme > Edit Scheme > Run > Diagnostics. With Thread Sanitizer enabled I wasn't able to access many NSView properties (e.g. bounds, frame) through LLDB.
I am fairly new to Objective-C. Currently porting my own library from C#/Java to objective C.
I now run into a very strange problem for me.
I have a NSArray with several Note objects. I want to transpose on of these notes:
//Note.h
- (Note *) transpose: (int) semitones;
//Main
NSArray *notes = [get it from somewhere];
Note *transposedNote = [[notes objectAtIndex:0]transpose:1]; //Doesn't compile
Note *transposedNote = [(Note*)[notes objectAtIndex:0]transpose:1]//Does compile
Is this happening because there is already a transpose method available in the general libraries?
I thought due to the dynamic nature of objective-C at runtime it would be checked which class objectAtIndex returns and then sends the message to it?
It is my understanding that there is no runtime type checking for the assignment operator in Objective C. Since an array can contain a mixture of types, there is no way for the system to know what objectAtIndex returns.
How about
Note *transposedNote = [notes objectAtIndex:0]; // first line
[transposedNote transpose:1]; // second line
? Notice in the reference that objectAtIndex: returns an id, you will see it is pretty obvious:
In the code above, because id can fit into any object, the first line doesn't need to cast it into Note. In the second line I'm just calling a method on a Note so the compiler is happy.
In your code you are calling methods on the returned id object, so the compiler doesn't understand what you are trying to do. Just assign it to a Note reference and it will be fine.
Yes, the error is because there's already a transpose: method in AppKit. And you're also right that it normally doesn't cause an error when you have two unrelated classes implementing methods with the same name. The reason you get an error is because the two methods either return incompatible types or take incompatible types as arguments. In your particular case, you're seeing both problems:
-[NSResponder transpose:] takes an id and returns void
-[Note transpose:] takes an int and returns an id
These are totally incompatible types, and the compiler does need to know the types involved even if it doesn't know what exact method is going to be called.
It does compile unless you have -Werror set to treat warnings as errors.
It might produce a warning if the compiler doesn't already know about the selector or if the selector is declared in more than one class. In the former case, it should be necessary only to import the interface containing the selector. In the latter case, you'll need to do the cast to suppress the error.