【问题标题】:using a delegate in a class method在类方法中使用委托
【发布时间】:2013-05-29 11:31:06
【问题描述】:

我想在类方法中调用一个委托。

下面的例子显然行不通,因为委托是在类方法中访问的实例变量。 (错误:在类方法中访问了实例变量 'delegate')

有alertnative吗?

我的头文件:

//  MyClass.h

#import <Foundation/Foundation.h>

@protocol MyDelegate <NSObject>

-(void)update;

@end

@interface MyClass : NSObject
{
    id<MyDelegate> delegate;
}
@property (nonatomic, retain) id delegate;

+(void)methodThatInvokesDelegate;
@end

我的实现文件:

//  MyClass.m
#import "MyClass.h"

 @implementation MyClass
 @synthesize delegate;

+(void)methodThatInvokesDelegate{
[delegate update];
 }

 @end

【问题讨论】:

  • 您缺少协议前面的“@”。您遇到的具体问题是什么?
  • @MikeM 以上只是一个例子。不是我实际使用的代码。但只是为了说明问题。我编辑了我的帖子并添加了“@”。错误i':“在类方法中访问的实例变量'delegate'
  • 为什么要这样做?也许你最好使用单例模式?
  • 如果你想向一个类发送一个简单的“更新”,使用 NSNotificationCenter stackoverflow.com/questions/16409448/… 可能就足够了。否则我会建议将方法设置为非静态或使用像@Marcel 所说的单例
  • 我想在类方法中触发一个事件。然后这个事件被另一个类订阅。

标签: iphone ios objective-c


【解决方案1】:

三个明显的选择:

  • 单例
  • 指向委托的静态变量(即类变量)
  • 使用 NSNotification 而不是委托

由于单例(和静态变量)无法跟踪委托的生命周期,我认为选项三是最干净的。

【讨论】:

  • 我不会选择选项 3,因为通知是“无针对性的”,而委派是“有针对性的”。有针对性我想说的是,委托指向一个特定的对象。
  • @AminNegm-Awad 我同意你的观点,但我们在这里尝试做一些有点奇怪的事情,所以肯定会有一些破损。在这种情况下,我会认为通知是害处较轻的。
  • 这肯定是一个品味主题。但我认为,静态变量并不是什么坏事。例如,对于通知,您将永远不会有返回值。
  • 在清零弱引用之前,静态委托将是等待发生的崩溃。静态 变量 通常很好,但我认为委托是一种特殊情况——因为它们依赖于但不控制另一个对象——尽管从技术上讲,它们只是一个变量任何其他。此外,通知具有用户字典,因此可以将值传回。
  • 如何传回一个值?以及谁的价值?你可以拥有大量的通知观察者。
【解决方案2】:

我想知道上下文,它可以让你在那种情况下运行。 ;-) 无论如何:

首先:为特定的实例对象设置委托。因此,您可以为同一(委托)类的不同实例设置不同的委托。

第二:类方法在该类的类对象中运行。这是一个不同于该类的每个实例对象的对象。所以没有什么可以称为“代表”。您可以拥有 100 名代表。

第三:你的类对象需要一个自己的委托。所以你必须在类对象中添加一个属性delegate,然后使用它。 (是的,可以有一个类对象的属性。我确实没有编写声明的属性。)如果您需要有关如何执行此操作的更多信息,只需对其进行评论。我会添加代码。

【讨论】:

    【解决方案3】:

    我不确定这是否会对您有所帮助,但我有类似的情况,我有一个用于数据加载的类方法。在这种情况下,类会实例化自己(这样调用者就不需要),直到完成。 (此代码经过一些编辑以使其在此处工作)

    头文件:

        @protocol DataLoaderDelegate2 <NSObject>
        - (void) dataLoaderSuccess:(NSData *)data loader:(id)theloader;
        - (void) dataLoaderFailed:(NSString *)error loader:(id)theloader;
        @end
    
        @interface DataLoader2 : NSObject {
                NSURLConnection *conn;
                NSMutableData   *receivedData;
                NSFileHandle    *fileHandle;
                id <DataLoaderDelegate2>    delegate;
        }
        @property (nonatomic, assign) id<DataLoaderDelegate2>delegate;
    

    调用以启动进程 - 对 initWithRequest 的调用传递“self”。

        + (DataLoader2 *)loadWithURLRequest:(NSURLRequest *)req delegate:(id)_delegate
        {
            DataLoader2 *dl = [[DataLoader2 alloc] init];
            [dl setDelegate:_delegate];
            conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
            return dl;
        }
    

    数据加载完成后,它会使用类似的东西进行清理

        - (void)connectionDidFinishLoading:(NSURLConnection *)connection
        {
    
                if ([delegate respondsToSelector:@selector(dataLoaderSuccess:loader:)])
                        [delegate dataLoaderSuccess:(fileHandle)?(id)fileHandle:(id)receivedData loader:self];
                [self autorelease];
        }
    

    【讨论】:

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