我有一个同时拥有iOS和OS X目标的项目。在编译OS X时是否有预处理器宏?我试过这个:
#if TARGET_OS_MAC
@interface BFNode : NSObject <NSPasteboardReading, NSPasteboardWriting> {
#else
@interface BFNode : NSObject {
#endif
但是TARGET_OS_MAC
似乎不起作用。当我尝试在iOS上运行应用程序时,我遇到编译器错误,因为它尝试编译第一行并且在iOS上没有定义NSPasteboardReading
协议。
我知道也有TARGET_OS_IPHONE
。如果我使用它并交换它有效的@interface
声明。
但是我有很多地方有代码,没有iOS版本,所以我也需要OS X的宏。
SOLUTION:
我最终在.pch文件中定义了一个新宏:
#define TARGET_OSX TARGET_OS_IPHONE == 0
答案 0 :(得分:10)
如果您正在使用Swift,那么language feature就是一个很棒的What it means to escape a string。如果您正在使用Objective-C,那么执行以下操作通常很有用:
#include <TargetConditionals.h>
#if TARGET_OS_IPHONE
@import UIKit;
#else
@import AppKit;
#endif
了解TARGET_OS_*
定义会使这更有意义。最值得注意的是,TARGET_OS_MAC
是任何Apple平台,这是非常出乎意料的。 !TARGET_OS_IPHONE
是macOS,TARGET_OS_IPHONE
是除此之外的任何内容。 iOS,tvOS和watchOS有更具体的定义。
来自TargetConditions.h
:
TARGET_OS_*
These conditionals specify in which Operating System the generated code will
run. Indention is used to show which conditionals are evolutionary subclasses.
The MAC/WIN32/UNIX conditionals are mutually exclusive.
The IOS/TV/WATCH conditionals are mutually exclusive.
TARGET_OS_WIN32 - Generated code will run under 32-bit Windows
TARGET_OS_UNIX - Generated code will run under some Unix (not OSX)
TARGET_OS_MAC - Generated code will run under Mac OS X variant
TARGET_OS_IPHONE - Generated code for firmware, devices, or simulator
TARGET_OS_IOS - Generated code will run under iOS
TARGET_OS_TV - Generated code will run under Apple TV OS
TARGET_OS_WATCH - Generated code will run under Apple Watch OS
TARGET_OS_SIMULATOR - Generated code will run under a simulator
TARGET_OS_EMBEDDED - Generated code for firmware
TARGET_IPHONE_SIMULATOR - DEPRECATED: Same as TARGET_OS_SIMULATOR
TARGET_OS_NANO - DEPRECATED: Same as TARGET_OS_WATCH
答案 1 :(得分:5)
这是因为在为iOS构建时也定义了TARGET_OS_MAC
。
请参阅http://sealiesoftware.com/blog/archive/2010/8/16/TargetConditionalsh.html。
我会尝试通过目标上的构建设置构建我自己的目标特定定义。
答案 2 :(得分:5)
根据TargetConditionals.h
中的文档(似乎截至2016年;任何平台):
+------------------------------------------------+
| TARGET_OS_MAC |
| +---+ +-------------------------------------+ |
| | | | TARGET_OS_IPHONE | |
| |OSX| | +-----+ +----+ +-------+ +--------+ | |
| | | | | IOS | | TV | | WATCH | | BRIDGE | | |
| | | | +-----+ +----+ +-------+ +--------+ | |
| +---+ +-------------------------------------+ |
+------------------------------------------------+
这告诉我们:
TARGET_OS_MAC
将1
用于(可能)在Apple平台上运行的任何Cocoa应用程序。
TARGET_OS_OSX
对于macOS目标只有1
TARGET_OS_IPHONE
为1
TARGET_OS_IOS
仅适用于iOS TARGET_OS_TV
仅适用于tvOS TARGET_OS_WATCH
仅适用于watchOS TARGET_OS_BRIDGE
仅适用于bridgeOS(目前它甚至不支持第三方应用,因此您可能始终认为这是0
)此外,还定义了这些:
TARGET_OS_SIMULATOR
仅适用于iOS, tvOS, and watchOS simulators。您可以使用上述#define
s TARGET_OS_WIN32
以防万一你想使用Apple的SDK制作Windows应用程序。我不会亲自了解除Apple以外的任何人(如iTunes,Safari和QuickTime)TARGET_OS_UNIX
适用于非macOS UNIX系统这些已被弃用,不应再使用了。也就是说,您可能会在代码中找到它们,所以这就是它们的含义:
TARGET_IPHONE_SIMULATOR
用于表示iPhoneOS模拟器TARGET_OS_EMBEDDED
用于表示iOS,tvOS和watchOS非模拟设备TARGET_OS_NANO
可能用来表示iPod Nano(我无法在线找到任何历史用法)需要注意的是the TargetConditionals.h
used in swift-corelibs-foundation明显不同,包括适用于Android,Cygwin的#define
以及其他未明确支持的技术工作平台。
我不完全确定如何做到这一点。我猜它是为了编译Swift Foundation框架,而不是为了消费它,因为Swift并没有消耗#define
。
答案 3 :(得分:1)
在TargetConditionals.h中查找整个列表,包括:
#define TARGET_OS_MAC 1
#define TARGET_OS_IPHONE 1
#define TARGET_IPHONE_SIMULATOR 1
答案 4 :(得分:1)
从Xcode 8 GM开始,这是iOS 10.0中 TargetConditionals.h 的相关部分:
#define TARGET_OS_MAC 1
#define TARGET_OS_WIN32 0
#define TARGET_OS_UNIX 0
#define TARGET_OS_OSX 0
#define TARGET_OS_IPHONE 1
#define TARGET_OS_IOS 1
#define TARGET_OS_WATCH 0
#define TARGET_OS_BRIDGE 0
#define TARGET_OS_TV 0
#define TARGET_OS_SIMULATOR 0
#define TARGET_OS_EMBEDDED 1
#define TARGET_IPHONE_SIMULATOR TARGET_OS_SIMULATOR /* deprecated */
#define TARGET_OS_NANO TARGET_OS_WATCH /* deprecated */
(在Xcode文本编辑器上方的'breadcrumb'中,iOS 10.0 > usr/include > TargetConditionals.h
)
...对于macOS来说,这是同一个文件:
#define TARGET_OS_MAC 1
#define TARGET_OS_WIN32 0
#define TARGET_OS_UNIX 0
#define TARGET_OS_OSX 1
#define TARGET_OS_IPHONE 0
#define TARGET_OS_IOS 0
#define TARGET_OS_WATCH 0
#define TARGET_OS_BRIDGE 0
#define TARGET_OS_TV 0
#define TARGET_OS_SIMULATOR 0
#define TARGET_OS_EMBEDDED 0
#define TARGET_IPHONE_SIMULATOR TARGET_OS_SIMULATOR /* deprecated */
#define TARGET_OS_NANO TARGET_OS_WATCH /* deprecated */
(在Xcode文本编辑器上方的'breadcrumb'中,macOS 10.12 > usr/include > TargetConditionals.h
)
TARGET_OS_MAC
在两个平台上定义为 1 ,但TARGET_OS_OSX
仅在
在文件的评论中,它们描述如下:
- TARGET_OS_MAC:生成的代码将在Mac OS X变体下运行。
- TARGET_OS_OSX:生成的代码将在OS X设备下运行。
我想当时的某些时候(可能是在宣布推出iPhone的时候?)有人认为iOS(né“iPhone OS”)符合“Mac OS X变种”的定义。
答案 5 :(得分:0)
我建议使用它:
#define TARGET_OS_OSX (!(TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH))
答案 6 :(得分:0)
我遇到了同样的情况,但是Swift需要它。
Apple开发者论坛上的此答案对于处理您所处的NSPasteboard
协议非常有帮助,但对于Swift。
https://forums.developer.apple.com/thread/16757
我最终做了:
#if os(iOS) || os(watchOS)
public protocol TFPasteboardReading { }
public protocol TFPasteboardWriting { }
#elseif os(macOS)
public typealias TFPasteboardReading=NSPasteboardReading
public typealias TFPasteboardWriting=NSPasteboardWriting
#endif
@objc(TFCategory)
public class TFCategory: TFBaseModel, TFPasteboardReading, TFPasteboardWriting {
...
}
那样,为macOS定义了TFPasteboardReading
和TFPasteboardWriting
,分别表示NSPasteboardReading
和NSPasteboardWriting
,而在iOS中则没有意义,但仍可以在iOS中引用。因此,这两种代码都可以正确编译。