如何在Objective-C类别中使用内部方法?

时间:2013-05-02 17:55:31

标签: ios objective-c objective-c-category

尝试从开源项目扩展功能,我写了一个类别来添加一个新方法。在这个新方法中,类别需要从原始类访问内部方法,但编译器说它找不到方法(当然是内部的)。有没有办法为类别公开此方法?

修改

我不想修改原始代码,所以我不想在原始类头文件中声明内部方法。

代码

在原始的类实现文件(.m)中,我有这个方法实现:

+(NSDictionary*) storeKitItems
{
  return [NSDictionary dictionaryWithContentsOfFile:
          [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:
           @"MKStoreKitConfigs.plist"]];
} 

在类别中,我想添加此方法:

- (void)requestProductData:(NSArray *(^)())loadIdentifierBlock
{
    NSMutableArray *productsArray = [NSMutableArray array];
    NSArray *consumables = [[[MKStoreManager storeKitItems] objectForKey:@"Consumables"] allKeys];
    NSArray *nonConsumables = [[MKStoreManager storeKitItems] objectForKey:@"Non-Consumables"];
    NSArray *subscriptions = [[[MKStoreManager storeKitItems] objectForKey:@"Subscriptions"] allKeys];
    if(loadIdentifierBlock != nil) [productsArray addObjectsFromArray:loadIdentifierBlock()];
    [productsArray addObjectsFromArray:consumables];
    [productsArray addObjectsFromArray:nonConsumables];
    [productsArray addObjectsFromArray:subscriptions];
    self.productsRequest.delegate = self;
    [self.productsRequest start];
}

在我调用storeKitItems的每一行中,编译器说:类方法“+ storeKitItems”未找到...

3 个答案:

答案 0 :(得分:5)

这是微不足道的,做出方法的前瞻声明。

不幸的是,在obj-c中,每个方法声明都必须在@interface内,因此您可以在类别.m文件中使用其他内部类别,例如

@interface MKStoreManager (CategoryInternal)
   + (NSDictionary*)storeKitItems;
@end

不需要实现,这只告诉编译器该方法在其他地方,类似于具有属性的@dynamic

如果您只想删除警告,您也可以将课程强制转换为id,以下内容也可以使用:

NSDictionary* dictionary = [(id) [MKStoreManager class] storeKitItems];

但是,我最喜欢的解决方案是稍微改变一下,让我们假设以下示例:

@interface MyClass
@end

@implementation MyClass

-(void)internalMethod {
}

@end

@interface MyClass (SomeFunctionality)
@end

@implementation MyClass (SomeFunctionality)

-(void)someMethod {
  //WARNING HERE!
  [self internalMethod];
}

@end

我的解决方案是将课程分为两部分:

@interface MyClass
@end

@implementation MyClass
@end

@interface MyClass (Internal)

-(void)internalMethod;

@end

@implementation MyClass (Internal)

-(void)internalMethod {
}

@end

并包括MyClass+Internal.hMyClass.m

中的MyClass+SomeFunctionality.m

答案 1 :(得分:1)

类别无法访问类的私有方法。与尝试从任何其他类调用这些方法没有什么不同。至少如果你直接调用私有方法。由于Objective-C是如此动态,您可以使用其他方法调用私有方法(这是一个坏主意),例如使用performSelectorNSInvocation

同样,这是一个坏主意。对类的实现的更新可能会破坏您的类别。

编辑:现在已发布代码 -

由于.h文件中未声明+storeKitItems方法,因此任何类别或其​​他类都不能访问私有方法。

答案 2 :(得分:0)

在您的类别实现文件中,您可以为方法

定义和非正式协议
@interface YourClasses (ExternalMethods)

+(NSDictionary*) storeKitItems;

@end

这将阻止编译器抱怨你不知道你类别中的方法storeKitItems。