Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios respondsToSelector:不为委托工作_Ios_Objective C_Ios5_Respondstoselector - Fatal编程技术网

Ios respondsToSelector:不为委托工作

Ios respondsToSelector:不为委托工作,ios,objective-c,ios5,respondstoselector,Ios,Objective C,Ios5,Respondstoselector,我是iOS世界的新手,在尝试将表视图中的值传递回主控制器时遇到问题 我正在研究的场景是 家庭控制器有一个按钮 单击“打开”按钮可打开第二个UIViewController中的项目列表 用户从列表中选择一项 所选项目将添加到主控制器上的另一个列表中 非常感谢对这个问题的任何建议: 这就是我在家准备赛格的方式 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { UIViewController *des

我是iOS世界的新手,在尝试将表视图中的值传递回主控制器时遇到问题

我正在研究的场景是

  • 家庭控制器有一个按钮
  • 单击“打开”按钮可打开第二个UIViewController中的项目列表
  • 用户从列表中选择一项
  • 所选项目将添加到主控制器上的另一个列表中
  • 非常感谢对这个问题的任何建议:

    这就是我在家准备赛格的方式

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
        UIViewController *destination = segue.destinationViewController;
        if ([destination respondsToSelector:@selector(setDelegate:)]) { 
            [destination setValue:self forKey:@"delegate"];
        }
    
    }
    
    SecondController有一个委托id,所以我假设委托被设置为“
    respondsToSelector
    ”为“setDelegate”返回true

    现在,在SecondController中,当用户选择一个项目时,我调用
    didSelectRowAtIndexPath
    &
    viewwilldiscover
    方法设置该项目并使视图消失:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        POSAllItemsCell *cell = (POSAllItemsCell *) [tableView cellForRowAtIndexPath:indexPath];
    
        item = [NSDictionary dictionaryWithObjectsAndKeys:cell.name, @"Name", cell.price, @"Price", cell.code, @"Code", nil];
    
        [self dismissViewControllerAnimated:YES completion:NULL];
    
    }
    
    - (void)viewWillDisappear:(BOOL)animated { 
        [super viewWillDisappear:animated]; 
    
        if ([delegate respondsToSelector:@selector(setSelection:)]) {
            [delegate setValue:item forKey:@"selection"];
        }
    }
    
    现在的问题是
    respondsToSelector
    for
    setSelection
    返回false,即使我的HomeController中有setSelection方法:

    - (void) setSelection:(NSDictionary *)dict {
        if (![dict isEqual:selection]) {
            ......
        }
    }
    

    如果我的问题不清楚或格式不正确,请提前道歉。顺便说一句,这是针对带有Xcode 4.2的iOS 5的,要让委派工作,您需要如下设置:

    FirstViewController.h
    头文件中,确保声明第二个视图控制器符合委派视图控制器的协议:

    @interface FirstViewController : UIViewController <SecondViewControllerDelegate>
    
    您会注意到,您不应该在
    prepareforsgue
    方法中使用
    UIViewController
    ,而应该将其强制转换为实际的视图控制器,以便设置该视图控制器的属性。这样,您就不必测试视图控制器是否响应,因为它要么定义了
    委托
    属性,要么没有(在这种情况下,您需要添加一个)

    要设置原始代理协议,通常在
    SecondViewController.h
    文件中遵循以下格式:

    - (void)setSelection:(NSDictionary *)dict {
        if (![dict isEqual:selection]) {
            ......
        }
    }
    
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        if ([[segue identifier] isEqualToString:@"someSequeIdentifierHere"]) {
            SecondViewController *sv = segue.destinationViewController;
            sv.delegate = self;
        }
    }
    
    @protocol SecondViewControllerDelegate <NSObject>
    - (void)setSelection:(NSDictionary *)dict;
    @optional
    - (void)someOptionalDelegateMethodHere;
    @end
    
    @interface SecondViewController : UIViewController
    
    @property (nonatomic, weak) id <SecondViewControllerDelegate>delegate;
    
    @end
    

    由于
    delegate
    在.h文件中定义为公共属性,因此您可以将其引用为
    self.delegate
    \u delegate
    ,但将其引用为
    delegate
    会使我认为您错误地将其定义为私有实例变量

    大约只有当您没有正确地将该
    委托
    分配给您的
    FirstViewController时,这种类型的模式才会对
    respondsToSelector:
    做出响应

    希望这有帮助

    试试这个:

    if ([destination respondsToSelector:@selector(setDelegate:)]) { 
        [destination performSelector:@selector(setDelegate:) withObject:self];
    }
    

    显示您如何在“主”视图控制器中声明委托。我可能在这里遗漏了一些内容,但我假设在应用程序启动时为我创建的委托是“自动”的。这就是我在“第二个”控制器中声明它的方式:@property(弱的,非原子的)id委托;如果您记录委托,它是非零的吗?为什么在这里使用键值编码(
    setValue:forKey:
    ),或者只使用
    If([destination respondsToSelector:@selector(setDelegate:)]){[destination setDelegate:self];}
    @newacct-这不起作用,因为编译器不知道目标声明了选择器setDelegate,并且给出了错误
    没有可见的@interface for'UIViewController'声明了选择器“setDelegate:”
    @newacct-如果他将目标声明为
    id
    类型,则您的建议确实有效对于
    UIViewController*
    “您可以将其引用为self.delegate或_delegate,但将其引用为delegate会使我认为您错误地将其定义为私有实例变量。”您假设他没有显式地将其合成。但如果他真的这么做了,,然后,他确实可以将实例变量引用为
    delegate
    @iwasrobed-无需检查该委托是否响应选择器
    setSelection:
    ,因为它必须响应,因为它实现了SecondViewControllerDelegate协议,并且该方法是必需的。@vacawama Xcode将警告您不要实现必需的委托方法,但仅此而已。您仍然可以编译和运行该程序,当它尝试调用该选择器时,它将失败。因此,除非您希望确保应用程序不会崩溃,否则“没有必要”。@iWasRobbed-使用警告构建是个坏主意。他们在那里是有原因的。我不确定投入额外的代码来避免我不注意它们是否值得。YMMV@vacawama也许你应该停止向唱诗班宣讲其他人的答案。。。如果你对一个问题有更好的答案,请回答。
    if ([destination respondsToSelector:@selector(setDelegate:)]) { 
        [destination performSelector:@selector(setDelegate:) withObject:self];
    }