目标C - 动态编译或不编译类和代码

时间:2018-03-19 12:38:00

标签: ios objective-c dynamic-programming

首先;我不知道这个问题是否重复。因为我不知道如何搜索这个问题。

让我用场景解释我的问题。

我有iOS 11项目(部署目标9.2)。我们称之为Master。

我编写了2个POD项目,而Master项目也为它们提供了参考。

POD1 has classes A.class B.class and C.class

POD2 has classes D.class E.class and F.class

主项目正在使用POD1 and POD2

这是一个问题;如果我想删除POD1引用并希望仅使用POD2分发项目,该怎么办?

我必须删除使用POD1的Master内的所有代码?我不这么认为......这是非常业余的方式。并且应该有专业的方式来做到这一点。

也许运行脚本?

也许在代码中放置一些标志,使用POD1类从构建中排除?所以我没有因为找不到文件而得到错误..

我知道使用

的方式
#ifndef HIDE_<insert name here>

CODE

#endif

但不要认为这是一种正确的方法..

任何想法&amp;欢迎提出建议。

谢谢。

1 个答案:

答案 0 :(得分:1)

使用Objective-C类别,您可以有条件地为不同的目标编译方法组。这是一个例子。

我们假设您有两个使用类A的目标。在一个目标(后台守护程序)中,您只需要类A的核心功能。在应用程序的GUI版本中,您需要使用相同的功能 plus 来支持用户界面。问题是您无法简单地编译守护程序目标中的所有类A,因为它将引用守护程序目标未链接到的Cocoa类。您需要隔离用户界面代码并仅在使用它的目标中编译/链接它。以下是:

基础课程

A.H

@interface A : NSObject
@property NSUInteger someProperty;
- (void)doSomething;
@end

A.M

@implementation A
- (void)doSomething
{
    // Do something useful
}
@end

现在在类别中定义GUI特定方法:

A + ViewAdditions.h

@interface A (ViewAdditions)
@property (readonly,nonatomic) NSView* view;
@end

A + ViewAdditions.m

@implementation A (ViewAdditions)
- (NSView*)view
{
    // Create a view that will display this object
    NSView* view = [[NSView alloc] initWithFrame:NSZeroRect];
    return view;
}
@end

在两个目标中,您都包含/编译A.m模块,因此两个目标都会编译包含其AsomeProperty方法的核心类doSomething。但是在GUI目标中,您还要编译A+ViewAdditions.m模块。在您的GUI应用程序中,A类具有view属性,但在您的守护程序中它不会。您可以在运行时测试:

A* a = [A new];
if ([a respondsToSelector:@selector(view)])
    NSLog(@"a.view is a %@",a.view.className); // prints "is a NSView"
else
    NSLog(@"a has no view property");

这可以扩展到子类:

B.h

@interface B : A
@end

B.m

@implementation B
@end

B + ViewAdditions.h

@interface B (ViewAdditions)
@end

B + ViewAdditions.m

@implementation B (ViewAdditions)
- (NSView*)view
{
    NSTextField* fieldView = [[NSTextField alloc] initWithFrame:NSZeroRect];
    return fieldView;
}
@end

和...

A* a = [A new];
B* b = [B new];
if ([a respondsToSelector:@selector(view)])
    NSLog(@"a.view is a %@",a.view.className); // prints "is a NSView"
if ([b respondsToSelector:@selector(view)])
    NSLog(@"b.view is a %@",b.view.className); // prints "is a NSTextField"

您应该了解类别的限制。最棘手的是您无法通过类别将实例变量或存储的属性添加到类中。但是类别方法可以访问类中的私有变量,并且我有时会在基类中定义仅由类别使用的私有ivars。你的风格可能会有所不同。