提问人:stevendesu 提问时间:10/2/2019 最后编辑:stevendesu 更新时间:10/3/2019 访问量:51
你能在 Objective-C 中创建只在库中可见的类方法吗?
Can you create class methods in Objective-C only visible within your library?
问:
我在 Objective-C 中的朋友类上发现了这个 StackOverflow 问题,它与我试图解决的问题相似,但并不完全相同。所以我想扩展他们的例子。
假设我想要一个能力,可以递给一只猴子多个香蕉,他会保留一个他自己的香蕉阵列。当我告诉他吃饭时,他会从他的阵列中吃东西。然后我可以让他随机给我一根香蕉:
香蕉.h
@interface Banana : NSObject
- (BOOL)isPeeled;
@end
香蕉.m
#import "Banana.h"
@implementation Banana
{
@private
BOOL peeled;
}
- (id)init
{
self = [super init];
if (self)
{
peeled = NO;
}
return self;
}
- (void)peel // PRIVATE METHOD
{
peeled = YES;
}
- (BOOL)isPeeled
{
return peeled;
}
@end
猴子.h
#import "Banana.h"
@interface Monkey : NSObject
- (void)give:(Banana *)aBanana;
- (void)eat;
- (Banana *)getBanana;
@end
猴子.m
#import "Monkey.h"
@implementation Monkey
{
@private
NSMutableArray *bananas;
}
- (id)init
{
self = [super init];
if (self)
{
bananas = [[NSMutableArray alloc] init];
}
return self;
}
- (void)give:(Banana *)aBanana
{
[bananas addObject:aBanana];
}
- (void)eat
{
BOOL hungry = YES;
for (int i = 0; i < bananas.count; i++)
{
if (!banana.isPeeled)
{
hungry = NO;
[banana peel];
break;
}
}
if (hungry)
{
NSLog(@"Monkey ANGRY!");
}
}
- (Banana *)getBanana
{
int r = arc4random_uniform(bananas.count);
return [bananas objectAtIndex:r];
}
@end
在这种情况下,将是我正在分发的库中的公共标头。我的库的预期用途如下所示:Banana.h
Monkey.h
客户端App.m
#import "MonkeyLib/MonkeyLib.h"
@implementation SomeClass
- (void)someMethod
{
Banana *oneBanana = [[Banana alloc] init];
Monkey *oneMonkey = [[Monkey alloc] init];
[oneMonkey give:oneBanana];
[oneMonkey eat];
Banana *twoBanana = [oneMonkey getBanana];
if (twoBanana.isPeeled)
{
NSLog(@"No sad monkeys!");
}
}
@end
上面代码的直接问题是我的库无法编译,因为该类没有接口定义方法(由Banana
peel
Monkey.m
)
我在这个问题的开头链接的 StackOverflow 问题建议创建第三个头文件:
BananaPrivate.h的
@interface Banana (PrivateMethods)
- (void)peel;
@end
然后我可以导入,我可以突然调用该方法。但是,这失败了,因为当我尝试导入时,我创建了一个碰撞 -- 我已经定义了导入时Monkey.m
BananaPrivate.h
peel
BananaPrivate.h
Banana
Banana.h
Monkey.h
我无法从 中删除,因为其中一个方法返回了 类型的实例!Banana.h
Monkey.h
Monkey
Banana
我发现了一个古怪的解决方法,通过子类化,如下所示:Banana
内部Banana.h
@interface InternalBanana : Banana
- (void)peel;
@end
然后,在我可以安全地.但是,这有两个问题:Monkey.m
#import "InternalBanana.h"
- 它仅适用于我的猴子实例化的香蕉(如果我库的用户实例化香蕉并将其传递给我的猴子,它将是香蕉而不是 InternalBanana)
- 我必须创建一个文件,但在此文件中我无法定义.尝试在 within 中定义将抛出一个未定义的错误,因为这是超类的私有变量。如果我在 within 中定义并且它只调用 ,那也会失败,因为没有定义方法。虽然这有效,但它确实会导致 Xcode 抛出警告,说没有方法定义(尽管有警告,它还是构建并运行)
InternalBanana.m
peel
peel
InternalBanana.m
peeled
peeled
peel
InternalBanana.m
[super peel]
Banana
peel
peel
这个猴子生意的正确解决方案是什么?
答: 暂无答案
评论
Banana (PrivateMethods)
peel
Banana
Banana
(PrivateMethods)
@private
-eat
hungry