我创建了Custom Container View Controller according to Apple’s guide,这意味着我没有使用segue。 要将数据从ChildVC发送到ParentVC,我使用以下模式。
在 ChildVC.h
中typedef void (^ActionBlock)(NSUInteger);
@property (nonatomic, copy) ActionBlock passIndexToParent;
然后在 ParentVC.m viewDidLoad
中childVC.passIndexToParent=^(NSUInteger imageIndex){
//do some cool stuff
}
ChildVC包含一个TableView,并且要单击的按钮位于表格的单元格中,因此我使用以下技术获取单击行的索引
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//…
//target action
[cell.myImageButton addTarget:self action:@selector(getIndexOfTapped:) forControlEvents:UIControlEventTouchUpInside];
//…
return cell;
}
- (void) getIndexOfTapped:(id)sender
{
NSLog(@“X image tap confirmed");
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
if (indexPath != nil)
{
NSLog(@"INDEX of X image tapped is %ld",(long)indexPath.row);
self.passIndexToParent(indexPath.row);//Thread 1: EXC_BAD_ACCESS(code=1, address=0X10)
}
}
现在,当我运行程序时,我得到了
Thread 1: EXC_BAD_ACCESS(code=1, address=0X10)
换行
self.passIndexToParent(indexPath.row);
没有其他错误数据。有没有帮助解决这个问题?
答案 0 :(得分:0)
我强烈建议不要使用这种模式。主要是因为创建保留周期太容易了。如果传递给子节点的块包含对父节点的强引用,那么除非在解雇父节点时手动将子节点块清零,否则您将无法中断保留周期。
相反,您应该在子项上创建委托协议。它看起来像这样:
//ChildVC.h
@class ChildVC
@protocol ChildVCDelegate <NSObject>
-(void)childVC:(ChildVC *)childVC didSelectIndex:(NSUInteger)index;
@end
@interface ChildVC
...
@property (nonatomic, weak) id<ChildVCDelegate> delegate;
...
@end
//ChildVC.m
if (indexPath != nil)
{
if ([self.delegate respondsToSelector:@selector(childVC:didSelectIndex:)]) {
[self.delegate childVC:self didSelectIndex:indexPath];
}
}
然后定义 - (void)childVC:(ChildVC *)childVC didSelectIndex:(NSUInteger)索引;父项中的方法,并确保将父项设置为子项的委托。
另请参阅:The #1 question on frequent iOS questions
但是,叹气,为了回答你的问题,你有时在没有设置时调用该块。在调用块之前,你需要检查。