【问题标题】:Using delegation vs "property reverse scope"使用委托与“属性反向范围”
【发布时间】:2014-02-09 04:19:38
【问题描述】:

我有一个从 VC1 到 VC2 的 push segue。在准备转到 VC2 的 segue 中,我使用“=”运算符将 VC2 的属性设置为 VC1 中属性的内容。然后我在 VC2 中更改了该属性的内容。我现在需要将该属性传递回 VC1。我的印象是我可以通过代表团来做到这一点。但是,一旦我在 VC2 中更改它,它似乎会“神奇地”自行更改。我真的不知道这个词是什么。它必须是“=”运算符为 VC1 和 VC2 中的属性分配相同的内存位置,使两者都指向它,对吗?请告诉我这个术语以及我是否应该保持这种状态或重做我的模型以便我使用委托。

谢谢。

编辑/添加:

所以VC1 prepareForSegue 中的这个property1 设置了VC2 的property1。然后我在 VC2 的 textFieldDidEndEditing 中更改 property2。当我运行程序时,property1 被静态分配在 VC1 中。然后我在VC2更改之前检查property1,它很好,然后我在它修改后检查它并正确修改。但是,当我返回 VC1(通过导航控制器中的后退按钮)时,我检查了 VC1 的 property1,它是新的修改版本。我以为我必须使用委托将其传递回 VC1。

我的问题是,这叫什么?某种范围或继承?我应该以这种方式设置我的程序,还是应该强制它使用委托从视图到模型?

VC1.M

@interface VC1()
@property(nonatomic, strong) NSMutableDictionary *property1;
@end

@implementation VC1

@synthesize property1= _property1;
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if ([segue.identifier isEqualToString:@"VC2_SEGUE"]){
        VC2 *mVC2 = (VC2 *)segue.destinationViewController;
        mVC2.property1 = self.property1;
    }
}

@end

VC2.H

@interface VC2: UITableViewController <UITextFieldDelegate>
@property(nonatomic, strong)NSMutableDictionary *property1;
@end

VC2.M

@implementation VC2

@synthesize property1 = _property1;

-(void)textFieldDidEndEditing:(UITextField *)textField
{
    // Get the cell in which the textfield is embedded
    id textFieldSuper = textField;
    while (![textFieldSuper isKindOfClass:[CustomCel class]]) {
        textFieldSuper = [textFieldSuper superview];
    }
    // Get that cell's index path

    NSIndexPath *indexPath = [self.tableView indexPathForCell:(CustomCell   *)textFieldSuper];

    NSMutableArray *newObject = [[self.property1 objectForKey:[NSString stringWithFormat:@"%i", indexPath.section]] mutableCopy];
    [newObject replaceObjectAtIndex:indexPath.row withObject:textField.text];

    [self.property1 setObject:newObject forKey:[NSString stringWithFormat:@"%i", indexPath.section]];

}

@end

编辑:

我真的很好奇为什么我在VC2中修改property1后在VC1中更改它。我只使用 NSString 做了同样的事情,并将 VC2 中的属性分配给本地 val,但是一旦我回到 VC1,它就没有坚持下去。可以解释一下吗:(

【问题讨论】:

  • 您能提供一些示例代码吗?我并没有完全遵循您想要实现的目标。
  • @StefanFisk 肯定的事情
  • 我没有看过代码,但是当你想要 pass-by-copy 时,它听起来像你 pass-by-reference。这可以通过在@property 中设置copy 属性来实现。
  • @trojanfoe 好的,感谢您提出这个想法,我想可能会有一些通过引用传递。使用委托传回不是很好的 mvc 做法吗?我应该利用这个按引用传递,还是忽略它/按值传递然后使用委托将属性返回给 VC1?
  • @user3213783 是的,委托是要走的路。 copy-by-value 在集合类型上的问题是您需要浅拷贝还是深拷贝,这取决于您要更改的内容。浅拷贝可以使用 @property 声明中的 copy 属性来完成,但是递归深拷贝需要自定义的 setter/getter 方法,而且工作量很大。

标签: objective-c inheritance ios7 delegates delegation


【解决方案1】:

Delegate 是一种在 VC2 代码区设置 VC1 属性的样式。 使用块可以让你的代码更清晰。 在VC2.h文件中

typedef void(^BeginEditBlock )(NSMutableArray *newObject, int section);

@interface VC2: UITableViewController <UITextFieldDelegate>
@property(nonatomic, strong) BeginEditBlock *editBlock;
@end

在 VC2.m 文件中

-(void)textFieldDidEndEditing:(UITextField *)textField
{
    // Get the cell in which the textfield is embedded
    id textFieldSuper = textField;
    while (![textFieldSuper isKindOfClass:[CustomCel class]]) {
        textFieldSuper = [textFieldSuper superview];
    }
    // Get that cell's index path

    NSIndexPath *indexPath = [self.tableView indexPathForCell:(CustomCell   *)textFieldSuper];

    NSMutableArray *newObject = [[self.property1 objectForKey:[NSString stringWithFormat:@"%i", indexPath.section]] mutableCopy];
    [newObject replaceObjectAtIndex:indexPath.row withObject:textField.text];

    if(self.editBlock){
        self.editBlock(newObject, indexPath.section);
    }
}

在 VC1.m 文件中。

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if ([segue.identifier isEqualToString:@"VC2_SEGUE"]){
        VC2 *mVC2 = (VC2 *)segue.destinationViewController;
        mVC2.editBlock = ^(NSMutableArray *newObject, int section){
            [self.property1 setObject:newObject forKey:[NSString stringWithFormat:@"%i", section]];

       };
    }
}

关于块描述是:here

【讨论】:

  • 我更喜欢这种风格而不是代表,它使耦合非常松散。
  • 如果我需要尽快在 VC2 中设置 VC1 中的值,这会更有用吗?就像 VC1 正在做一些等待它在 VC2 中设置的计算? - 在后台。
  • 我认为你应该先阅读我上面提到的块文件。 Block 是管理代码的好方法。上面的代码,block是一个属性,VC2一调用block,block里面的编码就会执行。
  • 在流程方面,它的作用与使用委托协议完全相同,但无需声明协议、实现方法等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多