如何禁用 XCode 编译器在 Objective-C 源代码文件中定义“-DXXX”

How to disable XCode compiler defines "-DXXX" in the Objective-C source code files

尝试使用 NS_BLOCK_ASSERTIONS #undef,但看起来设置中的释放默认选项被粗暴地焊接到构建过程中。诀窍是仅使用 .m 源代码文件指令(可能是编译指示)来禁用它,因为我处于无法控制 XCode 项目设置的情况,并且它们在 Release 中被设置为默认设置构建。

#undef NS_BLOCK_ASSERTIONS

#import <Foundation/Foundation.h>
#include <stdio.h>

@interface LoggingAssertionHandler : NSAssertionHandler
@end

@implementation LoggingAssertionHandler

- (void)handleFailureInMethod:(SEL)selector
                       object:(id)object
                         file:(NSString *)fileName
                   lineNumber:(NSInteger)line
                  description:(NSString *)format, ...
{
    NSString *failureMessageDescription = [NSString stringWithFormat:@"NSAssert Failure: Method %@ for object %@ in %@#%li. Reason: \"%@\"", NSStringFromSelector(selector), object, fileName, (long)line, format];
    printf("%s\n", [failureMessageDescription UTF8String]);
}

- (void)handleFailureInFunction:(NSString *)functionName
                           file:(NSString *)fileName
                     lineNumber:(NSInteger)line
                    description:(NSString *)format, ...
{
    NSString *failureMessageDescription = [NSString stringWithFormat:@"NSCAssert Failure: Function (%@) in %@#%li. Reason: \"%@\"", functionName, fileName, (long)line, format];
    printf("%s\n", [failureMessageDescription UTF8String]);
}

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSAssertionHandler *assertionHandler = [[LoggingAssertionHandler alloc] init];
        [[[NSThread currentThread] threadDictionary] setValue:assertionHandler forKey:NSAssertionHandlerKey];
        NSCAssert(true == false, @"Impossible.");
        NSLog(@"Hello, World!");
    }
    return 0;
}

问题是宏是在项目创建时添加的系统文件的一部分,这些文件是预编译的(预预处理)。您的 #undef 是稍后编译的,因此它无法更改已经预处理的 makros。

要更改此设置,请将 #undef 放在 .pch(预编译头文件)文件中,放在包含系统头文件之前。它可能看起来像这样:

#ifdef __OBJC__
  #undef NS_BLOCK_ASSERTIONS
  #import <Cocoa/Cocoa.h>
#endif