【问题标题】:Telling a custom delegate when to call a method告诉自定义委托何时调用方法
【发布时间】:2012-12-31 15:55:05
【问题描述】:

我在 中创建了一个包含各种方法的自定义类,并且我还在该类中添加了委托方法,可以从导入我的自定义类的另一个类中调用这些委托方法。特别是我正在使用iOS。这是我的头文件 (.h) 和实现 (.m) 文件的一个小示例:

//iCloud.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>

@protocol iCloudDelegate;
@class iCloud;

@interface iCloud : NSObject {
    __weak id<iCloudDelegate> delegate_;
}

@property (nonatomic, weak) id <iCloudDelegate> delegate;

//Methods (abridged for StackOverflow)
+ (void)checkCloudAvailability;

@end

@class iCloud;
@protocol iCloudDelegate <NSObject>
//Methods (abridged for StackOverflow)
@optional
- (void)documentWasSaved;
@required
- (void)iCloudAvailable:(BOOL)status;
@end

以及我的部分实现(.m):

#import "iCloud.h"
@implementation iCloud
@synthesize delegate;

- (void)documentWasSaved {
    [[self delegate] documentWasSaved];
}

-(void)iCloudAvailable:(BOOL)status {
    [[self delegate] iCloudAvailable:status];
}

+ (void)checkCloudAvailability {
NSLog(@"Checking iCloud availablity...");
NSURL *returnedURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];

if (returnedURL){
    NSLog(@"iCloud is available");
} else {
    NSLog(@"iCloud not available. ☹");
}
}

我查看了许多教程、SO 帖子、示例代码等,试图弄清楚如何告诉委托何时调用委托方法,但我无法找到任何东西。大多数帖子显示实现应该添加委托(使用&lt;DelegateName&gt; 语法),然而我的自定义类实现不是我想要使用委托的地方(它在另一个没有委托的类中正在创建)。

正如您在上面的示例代码中看到的,我已经添加了委托方法(在实现中),但据我所知,这一切都会在使用它的其他类中调用委托方法。如果这是正确的,那么我如何让委托调用这些方法(比如来自我的checkCloudAvailability 类,它不是委托方法之一)?这是我正在尝试做的一个示例:

+ (void)checkCloudAvailability
    if (returnedURL){
      [[self delegate] iCloudAvailable:YES]; 
    ...
}

当我尝试使用 [[self delegate] methodName]; 行时,我收到以下错误,Xcode 假装它不再知道我在说什么:

为什么会这样?为什么我不能告诉委托何时调用委托方法?这在委托方法中可以正常工作,但为什么不能在实现它的类中呢?

我们将不胜感激任何想法、想法、链接、教程、代码或帮助。

【问题讨论】:

    标签: objective-c objective-c ios class delegates


    【解决方案1】:

    错误说它找不到方法delegate类方法 的上下文中不可用(即用+ 符号表示的方法)。这可能看起来令人困惑,因为类方法内部的self 不对应于实例,而是对应于类;另一方面,属性delegate 属于一个实例,这意味着它不可用。

    要解决这个问题,您应该将checkCloudAvailability 设为实例方法,或者将其重写如下:

    +(void)checkCloudAvailabilityWithDelegate:(id<iCloudDelegate>)delegate {
        ...
    }
    

    【讨论】:

    • 在后一种情况下,我认为如果他只创建一个类方法checkCloudAvailability 来返回iCloud是否可用会更容易。在这种情况下,委托并不是真正必要的。
    • @Scott 我同意——我看到使用delegate 的唯一原因是为了与可以访问delegate 的东西保持一致。例如,如果多个 instance 方法可能重用此 class 方法,则它们可以共享检查 @optional 方法是否通过将委托传递给类来实现的代码方法。
    • 是的,你都说得对,这可能会简单得多,我同意。我在这里使用了你们的 cmets 来改变我的设计模式,它工作得很好。另外请注意,问题中的方法只是一个示例。
    【解决方案2】:

    你调用class方法+(void)checkCloudAvailability。 类方法中的“self”表示类对象,而不是实例对象。 但是为实例对象声明了委托变量。

    【讨论】:

      【解决方案3】:

      看这是一个类方法。我还将使用属性而不是实例变量:

      @property (weak, nonatomic) id<iCloudDelegate> delegate;
      @synthesize delegate = delegate_;
      

      【讨论】:

        【解决方案4】:

        当你在函数调用之前使用'+'注解时,它变成了一个静态方法。在静态方法中,不能调用'self'

        【讨论】:

        • 可以调用self,它只是表示不同的东西(一个类,而不是一个实例)。我认为这是 OP 混乱的最终根源。
        • 你在混用你的命名法。一方面,Objective-C 方法与函数不同,Objective-C 中也不存在静态方法。以+ 为前缀的方法是类方法,而不是静态方法。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-02
        • 2017-03-31
        • 1970-01-01
        相关资源
        最近更新 更多