I do have Objective-C Automatic Reference Counting set to YES, but I have
Objective-C Garbage Collection set to Unsupported
So I don't see how -fobjc-gc could be getting set. Is there something else that also sets it that I haven't noticed? I've tried a clean build, so it's not something sticking around.
I found the answer, indirectly, thanks to this question. It turns out, that to get rid of garbage collection, I need to BOTH turn off garbage collection in the compiler settings when I click on Build Settings under the Project, and under the Target. If they disagree, the target (which is the one I didn't notice) overrides. No amount of playing with the settings at the project level was fixing that.
Related
This might be a silly question, but I just wanted to know. I want my code to detect if ARC is enabled, programmatically. How do I do that? Is there is any flag that I could check? Actually the problem is that, I have written an open-source library. I have used release and retain in it. if some one else uses my library files using ARC enabled, I dont want them to get any errors. how do I achieve this? or is there any possible ways I can provide any tools to compile my library before using it?
#if !__has_feature(objc_arc)
//Do manual memory management...
#else
//Usually do nothing...
#endif
This is of course a compile-time check, you cannot check for ARC at runtime.
An alternative would be to set the -fno-objc-arc compiler flag for your files that use manual memory management in a project that otherwise uses ARC.
Whether you want to bother with this at all or just use ARC everywhere depends on how backward-compatible you want/need to be. Code that supports both ARC and MRC can get quite hard to read and maintain.
You don't detect it programmatically, it operates based on translations. That is, it is not like Garbage Collection -- which is process-wide, required all linked libraries to support (and implement it correctly in that mode). You can have some files compiled with ARC, and some without.
However, you can detect it at compilation.
As far as the distribution of your library: I would not bother with a translation based system, where ref count ops are conditionally enabled. I would (personally) just support one model (MRC in your case, until you choose to migrate it to ARC), then expect people to link to the library, or if they compile it in a target they configure, to disable ARC. Conditionally enabling/disabling code based on the presence of a feature is asking for tough bugs, particularly when it's likely to affect 9% of your library's lines of code.
NO, you can't, Xcode would not compile in ARC projects if your source uses retain-release
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.
I'm trying to compile using the LLVM GCC 4.0 compiler, and I get this error in multiple of my .m files: ARC forbids explicit message send of 'release'
I've tried using -fno-objc-arc as a compiler flag but that returns the error: Unrecognized command line option "-fno-objc-arc".
How can I solve this?
Simply remove all calls to -release. You're not allowed to call -release under ARC because the compiler will insert all the necessary retain/release calls for you. Read more about ARC here.
The other way is to use the conversion tool, and Xcode can convert your project to ARC (including removing these calls) for you:
To disable ARC entirely, change your build settings:
However I'd recommend you start using ARC, it will make things a lot easier and actually faster too.
If you happen to be using the ASI (http://allseeing-i.com/ASIHTTPRequest/How-to-use) api, refer to this answer as it needs to be built using -fno-obj-arc flags for specific classes... Files doesn't support the ARC feature, how to deal with and refer to the answer titled 'Disable ARC for that one class'
When trying to use -retain, -release, and -dealloc while building my application using automatic reference counting in Xcode 4.2, I get an error like the following:
Automatic Reference Counting forbids
explicit message send of 'dealloc'
Why am I seeing this error? Are -retain, -release, and -dealloc no longer allowed under automatic reference counting?
Basically:
When using ARC, it's all or nothing. Either the compiler is managing all of the retains/releases/deallocs for you, or it is doing nothing. You cannot intersperse your own calls to them, because the compiler wants to do it all itself. It can make absurd optimizations by doing this (for example, a method that returned an autoreleased object under Manual Memory Management may now produce an object that never ends up in an autorelease pool). If you were to start sprinkling in your own calls to retain and release, then the compiler would have to work with these and wouldn't be able to perform a lot of the optimizations that it wants (and that you should want).
And as an added bonus, invoking -retainCount is now a compiler error! OH HAPPY DAY!
in response to AliSoftware: we CNA mix ARTC and not-ARC frameworks, and also arc and not-ARC source.
(I did it..)
The basic ideas are:
1) compiler will insert/remove calls as a very-very-good cocoa programmer can do
2) cocoa is ANYWAY C code, so we have separate compilations, so the linker CAN link binaries produced by multiple sources. Think it as we can mix asm and cocoa, or C and pascal...
in main opinion the Appleadvantege over c# / java is here: we are alway allows to mix, and, using a COMPILER technique 8non a runtime..) we can rush performance beyond.
Under automatic reference counting, retain, release, and dealloc are not allowed.
If you have an existing code, you can keep using it as is with the -fno-objc-arc you can selectively disable ARC on any file.
If you want to disable ARC on MULTIPLE files:
Select desired files at Target/Build Phases/Compile Sources in Xcode
PRESS ENTER. (double click selects only one file)
Type -fno-objc-arc
Press Enter or Done
As I have pointed out in my answer on Xcode ARC, you can compile specific source files as non-ARC. Dave DeLong's answer is a bit off. It doesn't include the fact that you can instruct the compiler to compile source as non-ARC in an ARC-enabled project (as explained here).
EDIT: I have fixed all but two warnings now, so thank you all for the advice and the encouragement. The two warnings I have left would require me to change the database:
/Locations.xcdatamodel:tiles.Map: warning: tiles.Map -- relationship does not have an inverse
/Locations.xcdatamodel:Waypoint.description: warning: Waypoint.description -- property name conflicts with a method already on NSObject or NSManagedObject
I have an iPhone app that throws more than 100 warnings when I compile it, but it is time-tested and solid.
Should I care about warnings?
EDIT Because the respondents asked, here are some of my warnings:
Warning: Multiple build commands for output file /Users/andrewljohnson/Desktop/thetrailbehind/TrailTracker/build/Debug-iphonesimulator/Gaia Places.app/wrench.png
/Locations.xcdatamodel:tiles.Map: warning: tiles.Map -- relationship does not have an inverse
/Locations.xcdatamodel:Waypoint.description: warning: Waypoint.description -- property name conflicts with a method already on NSObject or NSManagedObject
/TrailTrackerAppDelegate.m:58: warning: passing argument 1 of 'initWithViewController:withTitle:' from distinct Objective-C type
/Users/andrewljohnson/Desktop/thetrailbehind/TrailTracker/Classes/TrailTrackerAppDelegate.m: In function '-[TrailTrackerAppDelegate applicationDidFinishLaunching:]':
/Users/andrewljohnson/Desktop/thetrailbehind/TrailTracker/Classes/TrailTrackerAppDelegate.m:202: warning: no '-initWithFrame:forHelpScreen:' method found
/Users/andrewljohnson/Desktop/thetrailbehind/TrailTracker/Classes/TrailTrackerAppDelegate.m:202: warning: (Messages without a matching method signature
/TrailTrackerAppDelegate.m:329: warning: 'gpsController' may not respond to '-setAccuracy:'
/Users/andrewljohnson/Desktop/thetrailbehind/TrailTracker/Classes
/TrailTrackerAppDelegate.m:411: warning: local declaration of 'tabBarController' hides instance variable
/TrailTrackerAppDelegate.m:422: warning: 'TrailTrackerAppDelegate' may not respond to '-getAudioPlayer:'
/Users/andrewljohnson/Desktop/thetrailbehind/TrailTracker/Classes/TrailTrackerAppDelegate.m:633: warning: 'Reachability' may not respond to '-isHostReachable:'
/Users/andrewljohnson/Desktop/thetrailbehind/TrailTracker/Classes/TrailTrackerMapView.h:18: warning: 'myTopoMapSource' defined but not used
warning: 'dbCache' defined but not used
/TrailTrackerAppDelegate.m:58: warning: passing argument 1 of 'initWithViewController:withTitle:' from distinct Objective-C type
/Users/andrewljohnson/Desktop/thetrailbehind/TrailTracker/Classes
/Users/andrewljohnson/Desktop/thetrailbehind/TrailTracker/Classes/TripViewController.m:68: warning: 'TripViewController' may not respond to '-checkForNullImages'
/Users/andrewljohnson/Desktop/thetrailbehind/TrailTracker/Classes/TripViewController.m:94: warning: 'TrailTrackerAppDelegate' may not respond to '-blamblamblam'
/Users/andrewljohnson/Desktop/thetrailbehind/TrailTracker/Classes/MapViewController.m:406: warning: passing argument 1 of 'initWithData:' from distinct Objective-C type
Yes. Some Warnings can be important.
It's best practice to turn a compiler's warning level to the highest setting, and to try to eliminate all warnings.
If a warning cannot be removed through refactoring code, and it has been checked and deemed safe, then many languages have 'pragmas' to silence the warning.
Update circa 2014: It is increasingly common to turn on a complier option that treats all warnings as errors. I personally do this.
My gut answer would be absolutely, wholeheartedly yes.
Compiler warnings are there to help you write clear and maintainable code, reducing the likelihood of bugs being introduced later on or cropping up at runtime.
The compiler will generally catch things like unused variables, access to uninitialised variables, failure to return correctly from a function, etc. These things may not be an issue now or in testing, but could easily come along and screw you later.
I would be going through those warnings and trying to fix them now. It will be time well spent.
Many of those warnings look like extraneous stuff in your program that's harmless. However, when you have 100 warnings you know don't matter (I'm not saying all of those don't matter, I'm just illustrating) and warning 101 that's very real shows up--the odds are you aren't going to see it.
I do not tolerate any warnings whatsoever. Occasionally this means adding a useless line or two of code because the compiler can't see that a conditional must execute or the like. (A case in front of me as I write this: 4 paths in a switch on a random number. 1 of the 4 must execute and each assigns a value to a variable. The compiler doesn't know it must have a value at that point so I added an extraneous assignment to shut it up.)
lol I guess it depends what the warnings are!!
If you have over 100 and yet it runs just fine, I'd guess that they are probably warnings of the type "Object xxx may not respond to message yyy" - i.e. the new methods you've created within your app have not been set up with an appropriate declaration in the header so your compiler isn't able to check whether they are valid method calls for (or more accurately, messages to send to) your custom classes.
Many warnings in objective-C actually warn you of an error that will crash the application - in fact, there is even an option within XCode to "treat all warnings as errors". The fact that your app runs shows that you are not suffering from this problem (or at least, have not yet).
However, even if all your warnings are benign (which I doubt), there is good reason for fixing them. If its regarding class methods, you'll be able to find out before you experience a crash whether or not your sending a valid message to it. And for most of the other types of warnings, you're better off knowing about it.
I guess the final exception is if you're using a lot of deprecated methods. Then you might decide to leave them be, although again that's a risky strategy.
So we're back to the beginning point - it depends what they are! However, I'm 99% sure that it will be a worthwhile exercise fixing them. They're there to help you, not it!
Definitely Yes. Otherwise why would it be called a Warning?
If I could give ObjC developers one piece of advice, it would be "use accessors, always." But if I could give them two pieces of advice, the second piece would be "turn on 'treat warnings as errors'."
Maintaining a zero warning policy in Cocoa is perhaps the best cost/benefit trade-off I know of. There are very few warnings that cannot be fixed easily in Cocoa. When writing portable C++, it is often very challenging (sometimes nearly impossible) to avoid warnings, but Cocoa has a single compiler on two very similar platforms. There's almost nothing you need to be doing in Cocoa that should be tripping the default warning set.
Warnings breed warnings. When you say "well, I know about those 121 warnings and they're ok," it's very easy to miss when it becomes 122 warnings and that new one does matter. If you have a warning that you really need to work around, then suppress the warning, but don't ignore them in the build output.
My team turns up warnings very high, and over time we've had to tune them back down a little bit, but we still build major Objective-C++ projects on Mac and iPhone under the following warning flags. There are a few of them that could certainly come out for a particular project, but this is my team's default set, and we don't take many out. I talk about it a little more in my discussion of project templates. The zip file there includes Shared.xcconfig which documents what each of these does and why it's turned on or off. But the default set that Xcode gives is a minimum.
GCC_TREAT_WARNINGS_AS_ERRORS = YES
WARNING_CFLAGS = -Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter -Wno-unknown-pragmas -Wextra-tokens -Wformat-nonliteral -Wformat-security -Winit-self -Wswitch-enum -Wswitch-default -Wfloat-equal -Wpointer-arith -Wredundant-decls -Winvalid-pch -Wlong-long -Wdisabled-optimization
OTHER_CFLAGS = -Wnested-externs -Wold-style-definition -Wstrict-prototypes -Wundeclared-selector
OTHER_CPLUSPLUSFLAGS = -Wsign-promo -Wundeclared-selector
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES
GCC_WARN_64_TO_32_BIT_CONVERSION = YES
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES
GCC_WARN_ABOUT_RETURN_TYPE = YES
GCC_WARN_MISSING_PARENTHESES = YES
GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES
GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES
GCC_WARN_SIGN_COMPARE = YES
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES
GCC_WARN_UNUSED_FUNCTION = YES
GCC_WARN_UNUSED_LABEL = YES
GCC_WARN_UNUSED_VALUE = YES
GCC_WARN_UNUSED_VARIABLE = YES
GCC_WARN_UNINITIALIZED_AUTOS = YES
Absolutely. You should always resolve your warnings. If you can't, you should at least know why the warning is there and why you can ignore it. To just ignore all compiler messages, (however innocuous as they may seem), is just a recipe for disaster.
YES