用于修复objc_msgSend错误参数数量的自我和委托的类型错误?

时间:2016-09-23 14:29:01

标签: ios objective-c ipad

我有一个iPad应用程序,几年前我使用Greg Coombs'IntelligentSplitViewController编写,允许在iPhone应用程序中生成类似于可旋转UITabBarController的布局。 iOS 10的最新版本以这种列表中早期版本previously been described的方式打破了这一点:objc_msgSend给出了一条错误消息:有一定数量的参数,而期望为0。

@rintaro对此的回答是对另一个方法(typed_msgSend)执行类型转换而不是使用objc_msgSend。在使用两个参数回复其他海报的代码时,这是:

id (*typed_msgSend)(id, SEL) = (void *)objc_msgSend;

Greg的代码稍微复杂一些,鉴于我在Objective-C中的弱点,我很难做出与他的代码类似的事情。 (不幸的是,格雷格病了,已经停止支持。)具体内容如下:

- (void)willRotate:(NSNotification*)notification
{
...
   if (UIInterfaceOrientationIsPortrait(toOrientation)) 
   {
      @try 
     {
         UIPopoverController *popover = [super valueForKey:@"_hiddenPopoverController"];
         objc_msgSend(theDelegate, @selector(splitViewController:willHideViewController:withBarButtonItem:forPopoverController:), self, master, button, popover);
     ...

所以问题是六个参数的数据类型是什么?我的尝试是:

  1. theDelegate - 不确定 - 尝试'id'或'id< UISplitViewControllerDelegate>'(来自声明)
  2. @selector ... - SEL(通过类比回答)
  3. self - 真的不知道 - 试过'id'
  4. master - UIViewController *(来自声明)
  5. 按钮 - UIBarButtonItem *(来自声明)
  6. popover - UIPopoverController *(来自声明)
  7. 这会构建,但在启动画面后主要崩溃。当然,它可能会因为某些其他原因而崩溃,但除非我确定我已经完成了类型转换,否则我无法知道。 (我多么希望这是Java。)

1 个答案:

答案 0 :(得分:1)

void (*my_objc_msgSend)(id, SEL, id, id, id, id) = (__typeof(my_objc_msgSend))objc_msgSend;  
my_objc_msgSend(theDelegate, @selector(splitViewController:willHideViewController:withBarButtonItem:forPopoverController:), self, master, button, popover);

在objc中,id是结构点。任何对象(哪个类继承自NSObject)都可以使用id

如果仍然崩溃,请发布日志。

在iOS 9之后,我们不推荐splitViewController:willHideViewController:withBarButtonItem:forPopoverController:,您应该使用splitViewController:willChangeToDisplayMode: