I am trying to add a Symbolic Breakpoint in XCode to check for UI engine modifications on the background thread.
What I am doing is the following:
However, the error message I am getting back is always:
Stopped due to an error evaluating condition of breakpoint 5.1: "!Thread.isMainThread"
Couldn't parse conditional expression:
error: use of undeclared identifier 'Thread'
UI Engine must be modified on main thread.
I do not understand why the breakpoint condition cannot evaluate my condition. Can someone explain what I may be doing wrong here? I have tried putting that in Obj-c as well, to no luck.
EDIT: Obj-C version, here: !(BOOL)[NSThread isMainThread]
EDIT 2: Xcode version Version 11.3 (11C29)
EDIT 3: Ok, so, closing XCode and reopening has gotten the Obj-C version "working" they pause on a breakpoint for something like, 4-5 minutes each time. This effectively makes these breakpoints unusable. Not sure how to resolve this.
I was able to get your original symbolic breakpoint working as expected by writing the condition as
(BOOL)[NSThread isMainThread] == NO
I suspect there's a better way, and comparing a BOOL directly to NO is very bad style, but at least it got me past the "doesn't work" stage to the "does work" stage.
To clarify, setting symbolic breakpoints and using conditions DOES work, but
I would hazard that self and Thread are not available as symbols for much of the UIKit framework because there is no debugging information available for most of it, hence the error: use of undeclared identifier 'Thread'.
See the answer in this post:
How to log out self when add a symbol breakpoint at -[UIViewController viewWillAppear] method
There is also additional info about creating symbolic breakpoints for child classes and a possible workaround using an objective-c condition here:
Using of symbolic breakpoints for child classes in Xcode?
That being said, if you are only interested in particular classes in your modules where that method (layoutSubviews) is invoked, you can specify the module inside your symbolic breakpoint, and if you have your own implementation of that method (e.g. you have overridden it in your class code), the condition Thread.isMainThread or !Thread.isMainThread will in fact work for that class.
I know this may not in fact solve your dilemma, especially if you need to check all the invocations of layoutSubviews, but I hope it at least helps to explain why a condition using Thread does not work all the time.
Related
As I'm not allowed to add an answer to several duplicated questions, I will ask this question and give also one answer ;-)
The undefined symbol was a call to a self written swift function. This function sits in an swift file with only "global" functions (no class in that file). The function is called from several classes and all was good until this morning.
Suddenly I got this link-error message when producing the release product. The funny think was, it was only for ONE function call. All other calls got no errors, and when I commented out this particular function call, all was good. And this function is a very easy one. There is only one function parameter (Int64) and it returns a CLocationCoordinate2D.
I checked all possible solutions found here and at other places in the web. I even copied the function 1:1 as a local function inside the class.. nothing worked.
The final solution was the compiler flag for optimization. For release builds the flag in "Swift Compiler - Code Generation" is set to "Fast, Whole Module Optimization".
After changing that to "Fast, Single Module Optimization", everything worked ...
I think it is simply a bug in the optimization engine.
.. maybe that will help others in similar situations.
In Swift 3.0, the automated changing of function names due to the "Omit Needless Words" rule has caused two functions in an ObjC class to be the same.
- (void)showLoader;
...and...
- (void)show __deprecated_msg("User 'showLoader'");
The problem is that these functions are within a third party Cocoa Pod (otherwise I would just delete the unnecessary 'show' function).
This results in getting the error "Ambiguous use of 'show'" when I try to invoke the function like this:
loader?.show()
Is there a way to reverse the automatic changing of function name in Swift 3.0 or to help the compiler know which function I want to invoke?
Thanks for your help!
See MartinR's answer to my similar question here: Converting to Swift 3 renamed my own Objective-C method
If you owned the code, you could use NS_SWIFT_NAME(showLoader()) after your method declaration to force the ObjC-to-Swift method conversion to be named what you want:
- (void)showLoader NS_SWIFT_NAME(showLoader());
I think it's worth mentioning even though in your case it doesn't exactly solve your problem because you don't own the code.
You can work around this by calling
loader?.perform(Selector("showLoader"))
You will see a warning from the compiler, but it will compile successfully, and things will work correctly at runtime.
I am trying to run unit test whereby I am getting an warning:
'FileName' may not respond to '-failWithException:'
I wanted to know why this warning occurs and how to fix that?
Either the FileName interface does not declare the failWithException: method, or you have not imported the header file in which the interface is declared.
Whatever sort of object FileName is, the compiler can't find a method named '-failWithException' in that class. The solution is to go implement that method on that class, or to make sure the compiler can find the header file where it already is implemented.
By the way, it's a warning instead of an error because, unlike for instance Java, Objective-C allows you to manipulate classes at runtime. So while you PROBABLY have a problem there, you don't DEFINITELY have a problem, so the IDE gives you a yellow warning rather than a red error. But in your case, this is almost certainly something you need to fix.
I have recently upgraded to Xcode 4.2 and its started to give me so many semantic warnings with my code...
one of them is "conflicting distributed object modifiers on return type in implementation of 'release'" in my singleton class..
I read somewhere about - (oneway void)release; to release this warning but once i put that in my code i start to getting compile error as "Duplicate declaration of release" not sure why and if you try to find the second declaration it shows in this line
SYNTHESIZE_SINGLETON_FOR_CLASS(GlobalClass);
Update: This is the post where it explained about - (oneway void)release;
how to get rid of this warning "conflicting distributed object modifiers on return type in implementation of release" ? and why its happening ?
The post you link to contains the solution to the problem in the title and explains why it happened to you.
However, from reading your question it appears that your new issue is caused by mis-applying the great advice in that post's answer. I am fairly certain you added the line
- (oneway void) release {}
in your .m file rather than amending your existing
- (void) release {
line with the extra word "oneway".
This would be why you get "Duplicate declaration of release". Yes, this is confusing because it's a duplicate definition that is invisibly creating the duplicate declaration. But I've just tried doing it your wrong way, and I get that "duplicate declaration" message.
I get the impression, perhaps wrongly, that you didn't realise you actually had a release method, particularly when you think adding the line will "release this warning".
Don't take all errors too literally, and always try to think what someone might really mean as it's often different from what they say, but do try and understand what is in your code, even in the classes you've taken off the shelf.
And to address other questions raised, the reason you're overriding release is because it is a singleton which is not usually released. You probably only have a definition in your code, which will suffice.
What Jonathan Grynspan has to say about specifying on both the declaration and the definition is broadly valid (and indeed the root of the issue) but it's important to recognise that in this specific case, the declaration is by Apple's foundation code which has changed.
So, if it's not clear already, amend the line that XCode finds problem with to include the word oneway.
When I run my code through the version 252 checker binary, there are no analysis errors. However, when I change to use the latest 253 checker, it returns a slew of errors, all of which do not make any sense. For example, here is an image of an error that it shows in my Safari browser after the scan-build script is complete:
This is a pretty common error that shows up in the error listing. As you can see, the method name has Copy at the end of it, but it is still reporting as incorrectly named.
Here is the breakdown of errors that I am now getting with checker version 253:
Bug Summary
Results in this analysis run are based on analyzer build checker-253.
Bug Type Quantity
All Bugs 83
Dead code
Unreachable code 17
Memory (Core Foundation/Objective-C)
Bad release 19
Leak of returned object 23
Object sent -autorelease too many times 24
The autorelease errors seem to be related to the fact that the analyzer is unable to see that the Copy methods are actually correctly named, and I tried to look for an example of unreachable code, but I could not really find any patterns or explanations of those errors, as the errors were all lines of code inside simple if statements. Here is one for example:
I suppose that this could be some bugs that were introduced in the latest version of checker that is causing these to show up as errors. Is there something else (some kind of build setting or issue with the scan-build script) that I could be missing here?
First, method names should start with lower case letters, not uppercase (save for abbreviations like URL). It may be that the static analyzer is tripping over the uppercase "Get".
Next, even with a lowercase "get", the method does not follow convention.
To quote the documentation:
Use “get” only for methods that return
objects and values indirectly. You
should use this form for methods only
when multiple items need to be
returned.
Thus, the analyzer is correctly identifying an issue.
I would suggest following the guidelines and using something like:
+ (NSArray *) modifiedOrNewPeople: (FMDatabase *) aDatabase;
Which would release an autoreleased array. If there is some reason you can't return an autoreleased object, please comment.