【问题标题】:Passing data using blocks in Objective-C在 Objective-C 中使用块传递数据
【发布时间】:2017-02-22 06:29:38
【问题描述】:

我有两个视图控制器,分别是 ViewControllerA 和 ViewControllerB。

在 ViewcontrollerB 上有 tableview 单元格。单击表格视图单元格时,我想将在 ViewControllerB 上选择的数据发送到 ViewControllerA 上的标签。

我知道它可以通过多种方式实现,但是如何通过块来实现。请建议。

提前致谢!

视图控制器 B

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *viewArr = [self.array objectAtIndex:indexPath.row];

    NSLog(@"the value obtained on cell is %@",viewArr);
    ViewController *vc=[[ViewController alloc]init];
    vc.aSimpleBlock(viewArr);   
}

【问题讨论】:

  • 在块中我们也可以用多种方式做 int,你能展示你尝试过的代码
  • 我还没有通过块实现它,我已经使用委托完成了它......但现在我想通过块实现同样的......但无法理解正确的实现方式。
  • 好的,我添加一些示例
  • 你也可以使用 NSNotifications。

标签: ios objective-c uitableview objective-c-blocks


【解决方案1】:

在您的 ViewController A 中

1)为块声明一个typedef,比如typedef void (^simpleBlock)(NSString*);

2) 创建一个像

这样的块变量
@property(nonatomic,strong)simpleBlock  aSimpleBlock;

3)在viewDidAppear/viewDidLoad中定义这个块

aSimpleBlock = ^(NSString* str){
        NSLog(@"Str is the string passed on tableView Cell Click..!!");
    };

在你的 ViewController B 你有 tableView 的地方

1)-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

只需拨打您的block

your_VC_A_Object.aSimpleBlock("Your_Label_String_here");

【讨论】:

  • 执行以下行时会出现 EXC_BAD_ACCESS 异常:your_VC_A_Object.aSimpleBlock("Your_Label_String_here");
  • @TestShroff 您正在那里创建新对象。无需创建新对象,只需将导航到 VC B 的对象引用传递给 VC B。当您创建新实例时,它将创建新的块变量,因此您将无法引用同一个块。
  • @TestShroff 欢迎.. 如果这解决了您的问题,请将其标记为正确答案,以便其他成员发现它有用。编码快乐..!!
  • “只需将您正在导航的对象引用传递给 VC B。”请多解释一下。
  • 假设您正在从 VC1 导航到 VC2。然后在 VC2 中创建 VC1 变量(但不要使用 alloc init 对其进行初始化)。现在当你要推送 VC2 时,这样做: VC2_object.VC1_Variable_you_created = self.
【解决方案2】:

You can define a block in viewControllerB and set it ViewController A, when select a cell, you can call this block and pass the value to it, something like:
In viewControllerB

// ViewControllerB.h
@interface ViewControllerB : UITableViewController

@property (nonatomic, copy) void (^didSelectCellBlock)(id obj);
@end

// ViewControllerB.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        NSString *str = [self.dataArray objectAtIndex:indexPath.row];
        if (self.didSelectCellBlock) {
            self.didSelectCellBlock(str);
        }
        ...
    }
}

在 ViewController A 中

 ViewControllerB *controllerB = [[ViewControllerB alloc] init];
 __weak __typeof(self) weakSelf = self;
 controllerB.didSelectCellBlock = ^(id obj) {
     weakSelf.label.text = (NSString *)obj;
 };

【讨论】:

    【解决方案3】:

    第一步

    最初将VC-B的父类添加到VC-A

    @interface ViewControllerA : ViewControllerB
    

    第二步

    ViewControllerB的接口中创建一个通用方法

    @interface ViewControllerB : UIViewController
    
    -(void)shareContent:(NSString*)currentText;
    

    第三步

    在那个 ViewControllerB 实现文件上

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
     {
         __weak typeof(self) weakSelf = self;
    
          dispatch_async(dispatch_get_main_queue(), ^ {
    
             [weakSelf shareContent: [_items objectAtIndex:indexPath.row]];
    
        });
    
    
    }
    

    第四步

    在您的 ViewControllerA 实现文件上

     -(void)shareContent:(NSString*)currentText
     {
    
       NSLog(@"Local details:%@", currentText);
     }
    

    选择-2

    对于替代方式,您可以从hereexample 获取样本

    【讨论】:

      【解决方案4】:

      我不知道这是否明智甚至可能。

      为了在视图控制器之间直接传递数据,我经常使用委托。我会向 B 添加一个委托属性并让它定义一个委托协议。我会让 A 实现该协议并让 B 调用这些协议方法来传递数据。当然,将 B 的委托设置为 A。

      【讨论】:

      • 是的,这是可能的,甚至是可行的,因为块比委托更快,也使用块我们可以进行内联执行,从而使代码更具可读性。但是你不能在任何地方都用块替换代表也是事实,有时代表比块更重要。
      【解决方案5】:

      那么在这种情况下,您必须提供来自 ViewControllerA 的块,以便另一个 (ViewControllerB) 可以处理它(作为属性)、保留它并在您选择表格行时调用它。

      但是对委托的好处呢?事实上,委托在这种情况下更像是一种标准模式。

      【讨论】:

      • 事实上委托更好,因为 (a) 它是标准模式,并且 (b) 它避免了 A 和 B 相互依赖。使用委托使 B 保持独立。
      • @michi 和 Brett Donald 我认为你们应该看看这个:stackoverflow.com/questions/12176961/…
      • 块在许多情况下肯定是有价值的。我只是不认为在这种情况下他们是正确的选择。
      猜你喜欢
      • 1970-01-01
      • 2012-09-27
      • 1970-01-01
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      • 2014-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多