有没有办法将类别添加到您无法访问其头文件的类?
出于测试目的,我想向UITableViewCellDeleteConfirmationControl
添加一个类别,但该类是(据我所知)私有框架的一部分。
我该怎么做?
详细说明(根据mihirios的要求):
我正在尝试扩展Frank测试框架,以模拟在您尝试删除UITableViewCell
时点击确认按钮(大红色"删除"按钮)。 Frank向tap
添加UIControl
方法。出于某种原因,Frank通常使用控件的方法不适用于UITableViewCellDeleteConfirmationControl
类(子类UIControl
)。
我已经创建了一种解决方法。我使用以下方法向UITableViewCell
添加了一个类别。
- (BOOL)confirmDeletion {
if (![self showingDeleteConfirmation]) {
return NO;
}
UITableView *tableView = (UITableView *)[self superview];
id <UITableViewDataSource> dataSource = [tableView dataSource];
NSIndexPath *indexPath = [tableView indexPathForCell:self];
[dataSource tableView:tableView
commitEditingStyle:UITableViewCellEditingStyleDelete
forRowAtIndexPath:indexPath];
return YES;
}
这将查找表的数据源并调用其tableView:commitEditingStyle:forRowAtIndexPath:
方法,该方法(根据UITableView
的文档)是用户点击确认按钮时系统所执行的操作。 / p>
这样做有效,但我希望通过向其添加UITableViewCellDeleteConfirmationControl
方法使tap
看似是一个可点击的按钮,覆盖Frank的默认方法。 tap
方法会找到包含确认按钮的单元格,然后调用[cell confirmDeletion]
。
当我尝试为UITableViewCellDeleteConfirmationControl
声明一个类别时,编译器会抱怨它无法解析界面&#39; UITableViewCellDeleteConfirmationControl&#39;。&#34;
当我尝试使用某人使用类转储生成的头文件时,链接器会抱怨它无法找到符号_OBJC_CLASS _ $ _ UITableViewCellDeleteConfirmationControl。
答案 0 :(得分:2)
出于测试目的,您始终可以使用NSClassFromString
获取类对象,然后使用class_replaceMethod
运行时方法来执行您需要的任何操作。有关详细信息,请参阅Objective-C Runtime Reference。
答案 1 :(得分:2)
据我所知,您不能使用类别,但您可以在运行时手动添加方法。
可能的方法是,创建一个新类,实现您想要的方法,并使用适当的objc-runtime函数将此方法发送到UITableViewCellDeleteConfirmationControl。有一些事情需要注意,比如存储原始功能以备以后使用以防超载,也可以在你的“类别”级别你需要注意,当你想打电话给超级,因为这不起作用,你有改为使用objc-runtime函数objc_msgSendSuper。
只要您不需要打电话给超级,这样就可以了:
#import <objc/runtime.h>
#import <objc/message.h>
void implementInstanceMethods(Class src, Class dest) {
unsigned int count;
Method *methods = class_copyMethodList(src, &count);
for (int i = 0; i < count; ++i) {
IMP imp = method_getImplementation(methods[i]);
SEL selector = method_getName(methods[i]);
NSString *selectorName = NSStringFromSelector(selector);
const char *types = method_getTypeEncoding(methods[i]);
class_replaceMethod(dest, selector, imp, types);
}
free(methods);
}
调用该方法的一个好处是在main.m中,例如:
@autoreleasepool {
implementInstanceMethods([MyCategory class], NSClassFromString(@"UITableViewCellDeleteConfirmationControl"));
return UIApplicationMain(argc, argv, nil, NSStringFromClass([YourAppDelegate class]));
}
但我不知道为什么你不只是在控制器类中移动确认处理。
答案 2 :(得分:0)
只要编译器可以(最终)链接到相关类,您就可以为它创建一个类别。更重要的问题是如何设计类别,因为您似乎无法访问原始类的源。