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"...
这是微不足道的,做出方法的前瞻性声明.
不幸的是,在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.m和MyClass+SomeFunctionality.m
类别无法访问类的私有方法。这与尝试从任何其他类调用这些方法没有什么不同。至少如果你直接调用私有方法。由于 Objective-C 是如此动态,您可以使用其他方式(例如 usingperformSelector或 with )调用私有方法(这是一个坏主意) NSInvocation。
再说一次,这是一个坏主意。类实现的更新可能会破坏您的类别。
编辑:现在已经发布了代码 -
由于该+storeKitItems方法未在 .h 文件中声明,因此任何类别或其他类都无法访问该私有方法。
| 归档时间: |
|
| 查看次数: |
5655 次 |
| 最近记录: |