【问题标题】:Having trouble with custom delegates自定义委托遇到问题
【发布时间】:2013-01-01 15:04:47
【问题描述】:

我在编程方面相当陌生(我没有接受过编程方面的教育——我所知道的一切都是通过阅读教程获得的)并且在 XCode 和 iOS 开发方面是全新的。到目前为止,我了解了开发 iOS 应用程序的基础知识,但我无法弄清楚委托是如何工作的。我理解使用委托背后的想法,但我不知道在尝试实现委托时我做错了什么。我创建了一个小示例(单视图应用程序)来说明我如何实现自定义委托,希望您能告诉我我做错了什么。

我正在使用 XCode 4.5.2、iOS6.0 并启用了 ARC。

在示例中,我创建了一个简单的 NSObject 子类 (TestClassWithDelegate)。 TestClassWithDelegate.h 看起来像这样:

@protocol TestDelegate <NSObject>

-(void)stringToWrite:(NSString *)aString;

@end

@interface TestClassWithDelegate : NSObject

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

-(TestClassWithDelegate *)initWithString:(NSString *)theString;

@end

TestClassWithDelegate.m 看起来像这样:

#import "TestClassWithDelegate.h"

@implementation TestClassWithDelegate

@synthesize delegate;

-(TestClassWithDelegate *)initWithString:(NSString *)theString
{
    self=[super init];

    [delegate stringToWrite:theString];

    return self;
}

@end

视图控制器 (ViewController) 由一个 UILabel 组成,我想在其中写入一些文本。 ViewController.h 看起来像这样:

#import "TestClassWithDelegate.h"

@interface ViewController : UIViewController <TestDelegate>

@property (weak, nonatomic) IBOutlet UILabel *testlabel;

@end

ViewController.m 看起来像这样:

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

@synthesize testlabel;

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.testlabel.text = @"Before delegate";
    TestClassWithDelegate *dummy = [[TestClassWithDelegate alloc]    initWithString:@"AfterDelegate"]; //This should init the TestClassWithDelegate which should "trigger" the stringToWrite method.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark Test delegate
- (void)stringToWrite:(NSString *)aString
{
    self.testlabel.text = aString;
}
@end

上面例子的问题是视图上的标签只写“Before delegate”,而我希望它写“AfterDelegate”。

非常感谢所有帮助。新年快乐。

【问题讨论】:

    标签: objective-c delegates


    【解决方案1】:

    您还没有在任何地方设置委托,所以它将是nil。您要么需要initWithString:delegate: 而不是initWithString:,要么(更好)只创建对象,设置委托,然后单独发送字符串。

    您可能犯了一个(常见的)错误,即假设@synthesize 实际上在您的代码中创建了一个对象并为其分配了一个值。它不是。它是(现在大部分是多余的!)编译器为属性创建访问器方法的指令。

    下面是您的委托类的一个稍微修改的示例,以及一些示例用法:

    .h 文件:

    @interface TestClassWithDelegate : NSObject
    
    @property (weak, nonatomic) id<TestDelegate> delegate;
    -(void)processString:(NSString*)string
    
    @end
    

    .m 文件:

    @implementation TestClassWithDelegate
    
    -(void)processString:(NSString *)theString
    {
       [delegate stringToWrite:theString];
    }
    
    @end
    

    用法:

    TestClassWithDelegate *test = [TestClassWithDelegate new];
    [test processString:@"Hello!"]; // Nothing will happen, there is no delegate
    test.delegate = self;
    [test processString:@"Hello!"]; // Delegate method will be called.
    

    【讨论】:

    • 非常感谢您的快速回复。问题中的示例是我快速创建的(它仍然抓住了我理解代表如何工作的问题的本质)。在我实现 .delegate = self 之后,它解决了我在其他项目中的问题。
    猜你喜欢
    • 1970-01-01
    • 2011-04-17
    • 1970-01-01
    • 2020-02-09
    • 1970-01-01
    • 1970-01-01
    • 2012-12-07
    • 2015-10-21
    • 2021-07-17
    相关资源
    最近更新 更多