can i use:
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
in managed code?
like c# or managed c++?
That should work in C++/CLI just as well as it does in standard C++, which is to say, it's officially not allowed to redefine keyword such as new, but most compilers will let you do it.
With __FILE__ there is no problem, although you probably want to store it in a managed string, if you want to use it from managed code.
Related
under Active Compilation Conditions i have added a new flag (for debug only) called SOMEFLAG.
the check is implemented like so and works great:
#if SOMEFLAG
print("SOMEFLAG is true");
#endif
it actually prints like i would expect. now, i need to examine the same flag from Objective-C class and it never evaluates to true. any idea why?
should i make this flag in other way?
in general my goal is to be able to detect when it is executed from another target, the build is triggered from the cli.
if there is other way that less limiting i would like to know.
thanks!
In Objective-C (and other C-like languages that use a preprocessor) the canonical way to check whether a symbol is defined would be using #ifdef, not #if. There is an #if directive in Objective-C, but it doesn't behave quite the same way as the Swift #if compiler directive.
I'm building a .Framework and I would like to offer to the developers using my framework the ability to hide or show the NSLogs that are within the framework.
I already use this solution
Prefix.pch
#ifdef PY_LOGS
# define PYLog(...) NSLog(__VA_ARGS__)
#else
# define PYLog(...)
#endif
and then use PYLog() in my frameworks so that the developer can set the PY_LOGS flag or not in the preprocessor macros.
It works perfectly but I would like a solution that allows the developer to call something like
[[MyFramework sharedInstance] setDebug:YES];
Does anyone know how to do this?
Look at using a common solution like LibComponentLogging.
Whats wrong with?
#ifdef PY_LOGS
# define PYLog(...) if([[MyFramework sharedInstance] isLoggingEnabled]){ NSLog(__VA_ARGS__); }
#else
# define PYLog(...)
#endif
Objective-C messaging efficiency is the least of your worries.
I'm working on a library and I would like to support both memory management approaches (ARC and MRR) in one codebase.
I don't want to force users to use special flags for my code (-fobjc-arc).
I know about the preprocessor test: #if __has_feature(objc_arc), but what is the best practice to use that to cover the all differences?
Does anyone have any experience with that to make it clean and easy to work with?
The preferable way would be to use some macros for translations between ARC and non-ARC, which I can use in my code.
=========
My problem was solved by the accepted answer, but as a tip for others, I found a blog post by John Blanco giving the best set of examples for how to handle my problem.
Refer the code of MBProgressHUD in github. I think, that's what you want.
#if __has_feature(objc_arc)
#define MB_AUTORELEASE(exp) exp
#define MB_RELEASE(exp) exp
#define MB_RETAIN(exp) exp
#else
#define MB_AUTORELEASE(exp) [exp autorelease]
#define MB_RELEASE(exp) [exp release]
#define MB_RETAIN(exp) [exp retain]
#endif
This is how they are using these macros
self.indicator = MB_AUTORELEASE([[MBRoundProgressView alloc] init]);
Either use ARC and instruct people who will use the code to set compilation flags per file (-fobjc-arc), and force them to do so by adding this to the header:
#if !__has_feature(objc_arc)
#error ARC must be enabled!
#endif
Or build as lib/framework with ARC enabled. Wrapping memory management code in preprocessor directives is a terrible idea.
One way to support both ARC and Non-ARC code is to go to the Target, Build Phases, and to the Compile Sources section.
From there you should see all your .m files. You can then add to any file -fno-objc-arc under the Compiler Flags to tell the compiler to ignore ARC.
Yeah, don't do this. You'll end up having to test your code fully twice for every change. And debugging everything twice. It isn't worth the effort.
You really really want to write your code purely ARC or purely non-ARC.
There are very few constructs that can appear in a header file that won't work in one or the other.
Looking at the define of NS_INLINE it seems that the advantage of using it over static inline is compiler compatibility, is that correct? Should NS_INLINE always be used instead of static inline on c functions in objective-c projects?
#if !defined(NS_INLINE)
#if defined(__GNUC__)
#define NS_INLINE static __inline__ __attribute__((always_inline))
#elif defined(__MWERKS__) || defined(__cplusplus)
#define NS_INLINE static inline
#elif defined(_MSC_VER)
#define NS_INLINE static __inline
#elif TARGET_OS_WIN32
#define NS_INLINE static __inline__
#endif
#endif
Looking at the define of NS_INLINE it seems that the advantage of using it over static inline is compiler compatibility, is that correct?
Only in part. You must assess the dominant toolchain here, and ask "why was static inline not used, or why was it inadequate?". The dominant toolchain contains the attribute __attribute__((always_inline)). So there are really two parts to this:
a) Compatibility So it adds compatibility for multiple compilers.
b) Use of __attribute__((always_inline)) in the dominant toolchain. inline has devolved to be a simple request to inline. With always_inline, the compiler can still reserve the right to not inline the function (for obvious reasons). However, it also says "trust me, I want this inlined -- compiler, inline this if possible". This attribute restores some of the ability to inline to the programmer. This can be used for performance, but I suspect (in this case) that it has more to do with reduction of the number of private exported functions, rather than performance requirements.
Should NS_INLINE always be used instead of static inline in objective-c projects?
No. __attribute__((always_inline)) should be reserved for people who have had a lot of experience optimizing programs, and with use of this facility. This attribute can be applied to C functions, C++ methods, and other static calls. It cannot be applied to ObjC class or instance methods (which are dynamic). I mention that because the compiler, optimizer, and LTO are very good at what they do. Meanwhile, improper use of inlining can have (any of) several performance penalties. The exception (for people who have not spent significant time optimizing) is of course when one takes the time to measure the differences it makes.
Yes, it's for compiler compatibility, but I think it's more for the use of the frameworks than for your own code. You're free to use it, of course, but I wouldn't bother.
This is kind of a silly question, but really, how can i tell whether i am using ObjC version 2 or something else?
I can always assume "the latest", but i'd rather know :)
Is there a command line check i can run? Please advise
If you are running 10.5 or later, or any version of iOS, your computer is running Objective-C 2. If you are writing code which you want to work on systems before this, you can check for the __OBJC2__ macro, which will be defined only for Objective-C 2 and later systems.
#ifdef __OBJC2__
// use objective-c 2
#elif defined(__OBJC__)
// use objective-c 1
#else
// no objective-c
#endif