¿Cómo usar un método interno en una categoría Objective-C?

Tratando de ampliar las capacidades de un proyecto de código abierto, escribí una categoría para agregar un nuevo método. En este nuevo método, la categoría necesita acceder a un método interno de la class original, pero el comstackdor dice que no puede encontrar el método (por supuesto, es interno). ¿Hay alguna forma de exponer este método para la categoría?

EDITAR

No quiero modificar el código original, por lo que no quiero declarar el método interno en el file de encabezado de la class original.

El código

En el file de implementación de class original (.m), tengo esta implementación de método:

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

En la categoría, quiero agregar este método:

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

En cada línea en la que storeKitItems comstackdor storeKitItems dice: método de class "+ storeKitItems" no encontrado …

Una categoría no tiene acceso a los methods privados de una class. No es diferente a tratar de llamar a esos methods de cualquier otra class. Al less si llamas directamente al método privado. Dado que Objective-C es tan dynamic, puede llamar a methods privados (que es una mala idea) utilizando otros medios, como usar performSelector o NSInvocation .

Una vez más, esta es una mala idea. Una actualización de la implementación de la class podría romper su categoría.

Edit: Ahora que hay un código publicado –

Como el método +storeKitItems no se declara en el file .h, ninguna categoría u otra class pueden acceder al método privado.

Esto es trivial, haga una statement de avance del método.

Desafortunadamente, en obj-c, cada statement de método debe estar dentro de @interface , por lo que puede hacer que funcione en su file .m categoría con otra categoría interna, por ejemplo

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

No se necesita implementación, esto solo le dice al comstackdor que el método está en otro lugar, de manera similar a @dynamic con properties.

Si solo está interesado en eliminar la advertencia, también puede enviar la class a id , lo siguiente debería funcionar también:

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

Sin embargo, mi solución favorita es hacerlo de manera diferente, supongamos el siguiente ejemplo:

 @interface MyClass @end 

 @implementation MyClass -(void)internalMethod { } @end 

 @interface MyClass (SomeFunctionality) @end 

 @implementation MyClass (SomeFunctionality) -(void)someMethod { //WARNING HERE! [self internalMethod]; } @end 

Mi solución es dividir la class en dos partes:

 @interface MyClass @end 

 @implementation MyClass @end 

 @interface MyClass (Internal) -(void)internalMethod; @end 

 @implementation MyClass (Internal) -(void)internalMethod { } @end 

E incluya MyClass+Internal.h de MyClass.m y MyClass+SomeFunctionality.m

En su file de implementación de categoría, puede definir un protocolo informal para el método

 @interface YourClasses (ExternalMethods) +(NSDictionary*) storeKitItems; @end 

Esto evitará que el comstackdor se queje de no saber el método storeKitItems en su categoría.