【问题标题】:Two Independent Delegate Methods in a Class一个类中有两个独立的委托方法
【发布时间】:2013-08-19 09:16:46
【问题描述】:

我在一个类中有两个独立的委托方法。

    - (void)delegateMethod1:(id)data {
         self.data = data;
    }

    - (void)delegateMethod2 {
         [someClass sendData:self.data];
    }

现在,这有时可以正常工作,但其他时候,delegateMethod2 在 delegateMethod1 之前被调用。

我需要知道如何优雅地管理这行:[someClass sendData:self.data]; 只有在 delegateMethod1 和 delegateMethod2 都被调用时才会被调用。

我知道我可以通过在每次委托调用时使用变量来设置某些内容来做到这一点,但必须有一种优雅的方式来做到这一点。

有什么帮助吗?

【问题讨论】:

  • 委托方法是如何调用的?
  • 它们在不同的事件上被独立调用。重要的是两者都在很短的时间内被调用。
  • 你的问题似乎有点混乱。您已经将 [someClass sendData:] 方法放在了 delegateMethod2 中,然后您说 [someClass sendData:] 应该只在 delegateMethod1 和 delegateMethod2 都被调用之后才被调用。这怎么会发生?如果调用了 delegateMethod2,那么它将直接调用 [someClass sendData:] 方法。请详细说明。
  • ^ 你是对的,这有点令人困惑。在我的示例中,我在delegateMethod2 中执行了[someClass sendData:],因为这是当前实现中的方式,因为通常delegateMethod2 在delegateMethod1 之后调用,但不确定。我不介意在 delegateMethod2 以外的地方调用 [someClass sendData:]。
  • @NSFeaster: 所以[someClass sendData:self.data]应该在两个委托方法都被调用之后调用?

标签: iphone ios objective-c ipad cocoa-touch


【解决方案1】:

记住哪个代表已被调用对我来说似乎是最简单和最干净的解决方案。 但是您可以通过将检查移动到单独的方法来使其对称,这样 首先调用哪个委托并不重要:

- (void)checkIfDataCanBeSent {
    if (self.method1called && self.method2called) {
         [someClass sendData:self.data];
    }
}

- (void)delegateMethod1:(id)data {
     self.method1called = YES;
     // ...
     [self checkIfDataCanBeSent];
}

- (void)delegateMethod2 {
     self.method2called = YES;
     // ...
     [self checkIfDataCanBeSent];
}

(我假设所有委托方法都在主线程上调用,否则 必须添加一些同步。)

【讨论】:

    【解决方案2】:

    我相信,使用指示性变量是克服这个问题的最优雅的方法。但是这个变量必须保存在委托调用者对象中。

    伪类解释

    @interface DelegateCaller
    {
       BOOL hasCalled1stMethod;
    }
    @property(nonatomic,weak) id delegate;
    @end
    
    @implementation DelegateCaller
    
    -(void)in_some_process_1
    {
       [self.delegate delegateMethod1]; //call
       hasCalled1stMethod = YES; //set indicator
    }
    
    -(void)in_some_process_2
    {
       if(hasCalled1stMethod)
        {
           [self.delegate delegateMethod2]; //call
           hasCalled1stMethod = NO; //reset indicator for reuse, if required.
         }
    }
    
    @end
    

    这样您就不必在委托本身中维护任何变量,因为调用的规则是在调用者对象本身中维护的。

    另一种情况: 如果从某个object1调用delegateMethod1,从某个其他object2调用delegateMethod2,那么指示性变量方法再次是最优雅的方式(在这种有限的场景中)

    伪类解释:

    @interface ClassDelegateObject //aka the callee
    {
      BOOL hasCalledMethod1;
    }
    @end
    
    @implementation ClassDelegateObject
    
    -(void)delegateMethod1:(NSData*)data
    {
       self.data = data; 
       hasCalledMethod1 = YES; //set the indicator.
    }
    
    -(void)delegateMethod2
    {
       //here relying on the self.data!=nil will not be fruitful
       //in case the self.data is not nil and hold some previous garbage data then
       //this logic will fail.
    
       if(hasCalledMethod1) 
       {
         [someClass sendData:self.data]; 
         hasCalledMethod1 = NO; //reset the variable for reuse if required.
       }
    }
    
    @end
    

    【讨论】:

    • 你假设两个代表都是从同一个类中调用的,这是不正确的。
    • 好的,请在您的问题中编辑并添加这条信息。
    【解决方案3】:

    我建议您重新考虑代码的工作原理。也许您可以检查是否没有数据,如果有,请在准备好后发送:

    - (void)delegateMethod1:(id)data {
         self.data = data;
         if (self.dataShouldBeSentWhenReady) {
           [self sendData];
         }
    }
    
    - (void)delegateMethod2 {
         if (self.data) {
           [self sendData];
         } else {
           [self setDataShouldBeSentWhenReady:YES];
         }
    }
    
    - (void)sendData {
        [self setDataShouldBeSentWhenReady:NO];
        [someClass sendData:self.data];
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-15
      • 2011-03-29
      相关资源
      最近更新 更多