Is there a way to show warning on not using weak self? - objective-c

Every few months, I get the same problem of a ViewController not getting dealloced because of not using weak-self in a block.
Is there any way of making Xcode warn me about this?
Thanks.

This might help -Warc-retain-cycles
Also, if instead of Build, you choose Analyze in Xcode, this will give you more information about bad practices in the code which includes information about using weak variables.
Another level further is to use Infer, a static analyzer for iOS/Android that Facebook open sourced: www.fbinfer.com
Also, see: http://fuckingclangwarnings.com/ for other warnings. I just have '-w' set on my project to get all the standard warnings

Related

Objective-c static analysis tool

My crash reporting service is showing a large number of mystery crashes for an iOS app. For a few reasons I suspect the code is trying to perform a selector on an object that doesn't have the particular selector.
How can I statically analyze the code to find the erronous selector?
I'm writing Objective-C code using Xcode 4.6 on OS X 10.8. I'm ok with a tool that doesn't pick up things like calling performSelector where the selector is built from a string etc. I think a basic tool will work.
Select "Analyze" from the "Product" menu in Xcode. Or press shift+command+B.
It's invaluable for identifying routine memory management stuff in MRC. But it's still useful for ARC programs.
You might also want to try setting an exception breakpoint for all exceptions.
I'd also refer you to the Debug and Tune Your App section of the Xcode User Guide. Or Ray Wenderlich's My App Crashed, Now What? series.
By the way, while the analyzer helps, I don't think it will find incorrect selectors. You might want to share how you're using selectors, because it you're using performSelector, there are often better patterns. Sometimes you have to use it, but frequently there are other patterns that are more robust. Or if you absolutely need to use selectors, add runtime respondsToSelector checks. For example:
NSAssert([object respondsToSelector:#selector(someMethod:)], #"%# does not respond to selector someMethod:", object);
Or, conditionally perform the selector if it responds to it (this is how you perform a method that might be conditional on a particular iOS version):
if ([object respondsToSelector:#selector(someMethod:)])
[object performSelector:#selector(someMethod:)];

No visible #interface for

I have gotten this error on several occasions and am unclear as to what causes the error in general. After looking for over an hour on stack overflow and google I still don't have an answer. Could someone help?
I've seen several specific answers but nothing that says why the error happens, only "do x", or "do y".
I haven't included code yet because I want to know the reason that this error happens in general so I can fix my code in the future whenever I get this error.
There are lots of reasons it could happen, but generally it's saying that at the line of code it flags, it doesn't see any evidence that the selector you are referencing is in the interface of the type it thinks the object has.
In this example,
No visible interface error
They declared operandStack with the wrong type.
In this one
http://www.raywenderlich.com/forums/viewtopic.php?f=2&t=3312
They had a typo in the selector name
Any chance you are on Xcode 4.2 (or less), running code that was written on Xcode 4.3? In 4.3+ Xcode doesn't require you to declare private methods at all, it just assumes that methods written in the implementation file (without declarations in the interface) are private. But in Xcode <= 4.2, this will throw an error and those methods need to be at least declared privately
I just had this problem; mine was caused by me setting the method as a class method rather than an instance method. Very silly.
Another reason can be when using categories in libraries and you haven't set -ObjC (or -all_load) in the Other Linker Flags
Another common error ist to forget to write [someInstance setSomeValue:3]; instead of [someInstance someValue:3] (<- wrong). That what happened to me.
When I have run into this problem it turned out that Xcode had not reindexed files after changing Git branch. The solution is Delete Derived Data.
Using Xcode version 10.0 File -> Workspace Settings...(or Project Settings...) -> click on the little green circle and manually remove all files in DerivedData folder
I had this problem with NSSavePanel -beginSheetModalForWindow::, which obviously exists. I tried doing a clean rebuild as well as deleting the DerivedData, but no luck. I had copy-pasted and then modified, but I commented that out and typed out the call to -beginSheetModalForWindow and it started working. As far as I can tell I did not have any mistakes in the original call.

Disabling the "property's synthesized getter follows cocoa naming convention" warning

After upgrading Xcode to the 4.2, I'm going through and fixing all the new compiler warnings that I'm getting. One that is in a lot of places is the "property's synthesized getter follows Cocoa naming convention for returning 'owned' objects" warning. This is showing up in some code generated from web service WSDL files, so I don't want to change the property names just to satisfy a warning. Is there a compiler flag to disable these warnings? I've done the requisite googling, but I can't seem to find one.
I think the consensus is that a compiler flag like this doesn't exist, so the best route (in my situation) is to try to get the third party code generator to handle this appropriately.

Can I get a compiler/Xcode 'warning' when not releasing a retained object in the class dealloc method?

I have been using AppCode recently to circumvent an issue with Xcode in refactoring, and AppCode has nailed for me quite few "oups'es" whereby it warned me of un-released but retained object refs ... sniffing them out correctly through #property specifications too ! (not exactly what I was looking for mind you :) ), but a great help.
I was wondering if such a feature is available in Xcode (am using 4.1.1), and if yes how/where to enable it.
You can perform that kind of check using static analyzer - choose "Analyze" option from Product menu (or shift-cmd-B shortcut)
You could change the mode of analysis for 'Build' to deep under project build settings. By default its set to shallow.
Its located under the heading 'Static Analyzer - Analysis Policy'

"unrecognized selector sent to instance" in release mode and not in debug mode

I have an app which generate a lot of "unrecognized selector sent to instance" errors in Release mode an non in Debug.
Do you have any idea on where can be the issue?
Thanks and regards,
Are you releasing for the same SDK (10.6, 10.5...) as your debug mode? You might be calling a method that only exists in 10.6. This should produce a warning, however. Are you taking care of warnings rather than ignoring them?
If you release an object before you're done using it, and another object gets allocated at the same address, sending a message intended for the old object will hit the new object, and if they're of different classes, you'll get that exception.
Run the static analyzer (or, better yet, turn it on to run on every build in your build settings). The static analyzer will show you the simpler bugs of this nature—the “low-hanging fruit”.
Then, run your application under Instruments's Zombies instrument. If you still have a bug of this kind (but too sophisticated for the static analyzer to spot), the Zombies instrument will put a flag in the timeline when you send a message to a should-be-dead object. You can then begin hunting down the bug from there. Repeat until there are no more crashes.
It probably occurs because you are linking a framework in one mode and not the other, make sure when you add frameworks you are linking that you are in "All Configurations".