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

Lui*_*oza 5 objective-c ios objective-c-category

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

编辑

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

代码

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

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

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

- (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];
}
Run Code Online (Sandbox Code Playgroud)

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

Sul*_*han 5

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

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

@interface MKStoreManager (CategoryInternal)
   + (NSDictionary*)storeKitItems;
@end
Run Code Online (Sandbox Code Playgroud)

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

如果您只对删除警告感兴趣,您也可以将类强制转换id为以下内容:

NSDictionary* dictionary = [(id) [MKStoreManager class] storeKitItems];
Run Code Online (Sandbox Code Playgroud)

但是,我最喜欢的解决方案是有点不同,让我们假设以下示例:

@interface MyClass
@end
Run Code Online (Sandbox Code Playgroud)

@implementation MyClass

-(void)internalMethod {
}

@end
Run Code Online (Sandbox Code Playgroud)

@interface MyClass (SomeFunctionality)
@end
Run Code Online (Sandbox Code Playgroud)

@implementation MyClass (SomeFunctionality)

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

@end
Run Code Online (Sandbox Code Playgroud)

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

@interface MyClass
@end
Run Code Online (Sandbox Code Playgroud)

@implementation MyClass
@end
Run Code Online (Sandbox Code Playgroud)

@interface MyClass (Internal)

-(void)internalMethod;

@end
Run Code Online (Sandbox Code Playgroud)

@implementation MyClass (Internal)

-(void)internalMethod {
}

@end
Run Code Online (Sandbox Code Playgroud)

包括MyClass+Internal.h来自MyClass.mMyClass+SomeFunctionality.m


rma*_*ddy 1

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

再说一次,这是一个坏主意。类实现的更新可能会破坏您的类别。

编辑:现在已经发布了代码 -

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