如何在头文件中使用预处理器检查?

时间:2012-04-20 06:12:06

标签: ios xcode preprocessor conditional-compilation

好的我知道这里有很多帖子,但我还是遇到了麻烦。这是我正在尝试做的伪代码:

if(device is running iOS 5 or up)

    @interface RootViewController : UIViewController <UIPageViewControllerDelegate, UIGestureRecognizerDelegate>

    @property (strong, nonatomic) UIPageViewController *pageViewController;

else

    @interface RootViewController : UIViewController <LeavesViewDelegate, UIGestureRecognizerDelegate>

    @property (strong, nonatomic) LeavesViewController *leavesViewController;

endif

我是否正确地认为我需要使用预处理器宏检查,因为它位于头文件中?这是一个应用UIPageViewController的应用程序,如果它是iOS 5或更高版本(因此有UIPageViewController),否则它会回到Leaves(https://github.com/brow/leaves)。我已经设置了所有代码。只需要知道如何告诉编译器使用哪个。我认为使用任何运行时检查都不会起作用,因为我只需要UIPageViewController或Leaves编译的协议方法,而不是两者。而且我宁愿不使用完全独立的源文件。我尝试过使用这些检查:

#ifdef kCFCoreFoundationVersionNumber_xxx

#ifdef __IPHONE_xxx

#if __IPHONE_OS_VERSION_MAX_ALLOWED <__IPHONE_xxx

(使用各种xxx)

我在这里缺少什么?

编辑:

我在默认的.pch:

中也注意到了这一点
#ifndef __IPHONE_5_0
#warning "This project uses features only available in iOS SDK 5.0 and later."
#endif

让我想知道为什么同样的测试在我的.h文件中不起作用?

2 个答案:

答案 0 :(得分:0)

你不能这样做,因为预处理器宏是在编译时处理的。编译器应该如何知道你要定位的iOS,因为你在Mac上而不是iPhone上的每个人都在编译?

您无法在运行时轻松切换代码。有可能,但我不认为这意味着你想要它。

您可以在运行时检查特定SDK中是否提供了方法。这更简单直接。但是你无法实现目标。

我建议: 创建一个超类,其中没有包含特定的委托协议。在那里你写下你想要分享的所有代码。

然后从上层超类创建2个子类。在每个类中放入您的特定代码。

这就是它。 这是应该的方式。

答案 1 :(得分:0)

正如我在评论中提到的,你不能在编译时这样做。

但是这里有一个想法:似乎UIPageViewControllerDelegateLeavesViewDelegate的方法名称不相交,因此您可以将以下内容添加到头文件中:

-(void) leavesView:(LeavesView*)leavesView willTurnToPageAtIndex:(NSUInteger)pageIndex;
-(void) leavesView:(LeavesView*)leavesView didTurnToPageAtIndex:(NSUInteger)pageIndex;
-(void) pageViewController:(UIPageViewController*)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray*)previousViewControllers transitionCompleted:(BOOL)completed;
-(UIPageViewControllerSpineLocation) pageViewController:(UIPageViewController*)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation;

并没有在头文件中明确采用委托协议(省略< >内的委托。)

您在这两个类中使用的任何类都可以在* .m文件中实例化,条件如下:

// check for existence of class to determine which controller to instantiate
if(NSClassFromString(@"UIPageViewController"))
{
    // do something and set UIPageViewController delegate to "self"
}
else
{
    // do something else and set LeavesViewController delegate to "self"
}

最后,要进行编译,您可能需要转发声明所有使用它们的LeavesViewController - 和UIPageViewController相关类,并且可能需要utilize weak linking来表示某些框架。

我还没有使用Apple的UIPageViewController类和协议,所以我无法提供比这更多的见解。如果你得到了重点,请务必告诉我们:)