I've seen some compilers that lets you stop reading the file where ever in the file you want
and I want to know if obj-c has such thing here's an example, so you can understand:
#ifndef __OBJC__ // or #if !defined(__OBJC__)
#exit // do not continue compiling this file!
#endif
No, you can't simply stop compilation in the middle of the file. You'd have to structure it this way:
#if __OBJC__
// the rest of the file
#endif
Related
My service is included in 2 different platforms source files (iOS and watchOS), but I only want it to be compiled for watchOS platform only when a specified flag is set
Under main platform (iOS): alway include content
Under extension. Only include content when BUILD_FLAG(watch_feature) is 1
BUILD_FLAG is defined in config.h. config.h is always available under watchOS, but sometime not available under iOS platform.
TARGET_OS_IOS is always available to detect which platform the file is included
What I want is something like
#include "config.h"
#if TARGET_OS_IOS || BUILD_FLAG(watch_feature)
<content>
#endif
And sometime compiler complains config.h does not exist when compiling for iOS platform.
Here is my solution, but it is long. If anyone has better ideal, always welcome
Solution 1:
#if TARGET_OS_IOS
#if !defined(BUILD_FLAG)
#define MARKER
#define BUILD_FLAG(_) 1
#endif
#else
#include "config.h"
#endif
#if TARGET_OS_IOS || BUILD_FLAG(watch_feature)
#if defined(MARKER)
#undef MARKER
#undef BUILD_FLAG
#endif
<file content>
#endif
I'm taking a look at some legacy code I need to maintain, and I see many spots where there is the following query:
#if __has_feature(objc_arc)
// ARC is On
// ...
#else
// ARC is Off
// ...
#endif
What could be the motivation for keeping the 'ARC is Off' code?
There is little motivation to keep the no-ARC code in .m files, because you can choose to always compile those with ARC enabled.
In a .h file, you need to keep the no-ARC code if the header file might be imported by a .m file that still uses manual reference counting and the maintainer of that .m file doesn't want to convert the .m file to ARC.
Is there a way to replace a class name #import through a #define macro? I want it to be made in all my project and not just in one file. So I don't want to make a #ifdef / #ifndef in each class that include the #import that I want to replace.
Something like... I have
#import "ClassSomething.h"
in 5 classes. I want to replace it with an
#import "ClassSomethingCustom.h"
but only
#ifdef SomethingIsDefined
First, Objective-C's compiler (gcc or clang) do a good job of not cluttering the compiled source with duplicated header information. There's nothing wrong with including both headers - unless the headers re-define the same class (which is what I suspect is the case here).
Replace #import "ClassSomething.h" in all your files with #import CLASS_SOMETHING_HEADER
Then, in your .pch file, have the following:
#ifdef SomethingIsDefined
#define CLASS_SOMETHING_HEADER "ClassSomethingCustom.h"
#else
#define CLASS_SOMETHING_HEADER "ClassSomething.h"
#endif
This isn't really ideal, though, as pre-processor macros that deal with imports can lead to many unforeseen errors. It's not a common pattern and future developers may not properly understand what you've done.
Another option you might want to consider is a pattern that is commonly used in libraries that support both iOS and OS X.
#ifdef SOME_IOS_IDENTIFIER_I_FORGOT_TO_LOOK_UP
typedef UIColor MyColor
#else
typedef NSColor MyColor
#endif
In this case you'd name your two classes differently and use an alias to reference them in your source. Place the relevant imports in a "parent" header file like "MyProjectImports.h" or something. (where you'd import AppKit or UIKit)
Alternatively, you might want to consider using a Category on ClassSomething (i.e. "ClassSomething+Custom.h") to include the custom functionality you need. This will likely require some re-working of the logic underlying the two different classes, but in the files that need just the custom behavior, can conditionally #import the Category header and the other files can be left alone.
Without more knowledge on exactly how these two classes differ or will be used, I can't help you much further.
HtH
Put this into a header file:
#ifdef SomethingIsDefined
#import "ClassSomethingCustom.h"
#else
#import "ClassSomething.h"
#endif
and include this header file in you 5 classes.
You can change the content ClassSomething.h and put the #ifdef SomethingIsDefined only in there.
Perhaps what you need is to paste the code #dasdom wrote into your .pch file (pre-compiled header) file instead of every header. With that, you only need to paste it once and all the files will add this header automatically
#ifdef SomethingIsDefined
#import "ClassSomethingCustom.h"
#else
#import "ClassSomething.h"
#endif
I hope this helps you. Otherwise, please can you explain it deeply?
In my memory, there's some code that can let the NSLog not work when released.
I don't want to remove my NSLog in my code.It helps a lot on debug mode.
So I want to find a way that can leave them in my code, and also don't slow down the application when released.
Thanks for your help~~
A common way to remove all NSLog(…) call in a release is to create a macro that is between conditional preprocessor macro and compiles to nothing, something like this:
#ifdef RELEASE
# define NSLog(...) //remove loggin in production
#endif
Put this code in a .h file that is included in every other file, like a Defines.h that is #include'd in the prefix header (.pch).
RELEASE should be a preprocessor macro defined against the Release configuration in the "Build Settings" tab of your target.
Related Questions
Is it true that one should not use NSLog() on production code?
How to print out the method name and line number and conditionally disable NSLog?
You will need to replace NSLog with a custom macro.
Put for instance
#ifdef DEBUG
# define DLog(...) NSLog(__VA_ARGS__)
#else
# define DLog(...) /* */
#endif
#define ALog(...) NSLog(__VA_ARGS__)
in your prefix pch file.
Use ALog for cases where you always want log output regardless of the state of the debug flag, and DLog for log only in debug mode.
Source
What does __OBJC__ mean in Objective-C?
#import <Availability.h>
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#endif
It means the objective C compiler is being used. So you can create hybrid header files that can be used when compiling objective C or C or C++.
You could use it in a header file like this, if you wanted to publish a header file that defined an objective c object that you wanted to make available to c and c++ programmers/code :
#ifndef MYHEADER_H
#define MYHEADER_H
#ifdef __OBJC__
// Put objective C things in this block
// This is an objc object implemented in a .m or .mm file
#implementation some_objc_object {
}
#end
#endif
#ifdef __cplusplus
#define CLINKAGE "C"
// c++ things that .m or .c files wont understand go in here
// This class, in a .mm file, would be able to call the obj-c objects methods
// but present a c++ interface that could be called from c++ code in .cc or .cpp
// files
class SomeClassThatWrapsAnObjCObject
{
id idTheObject;
public:
// ...
};
#endif
// and here you can declare c functions and structs
// this function could be used from a .c file to call to a .m file and do something
// with the object identified by id obj
extern CLINKAGE somefunction(id obj, ...);
#endif // MYHEADER_H
This looks like your precompiled header file.
The precompiled header is shared between all C-dialect files in your project. It's as if all your .c, .cpp, .m and .mm files have an invisible #include directive as the first line. But the Cocoa header files are pure Objective C - trying to include them in a C/C++ source will yield nothing but syntax errors aplenty. Thus the #ifdef.
If your project only contains Objective C files (.m/.mm), which is the typical case, the #ifdef is not really necessary. But Xcode, which generated this header in the first place, protects you all the same.
Even if it's not a PCH file, this #ifdef only makes sense if the file is to be included from both Objective C and plain C/C++. But it does not hurt regardless.
Its just a macro symbol. In this case if that symbol is defined then your program should import the Apple Cocoa frameworks (Foundation and AppKit).
This woudl be the case if you were developing an objective-c / cocoa application. In other words, if you were developing a C++ / carbon application, the __OBJC__ symbol would not be defined and those objective-c dependant frameworks would not be imported.