0

私はプログラミングの初心者であり (プログラミングの教育を受けていません。知っていることはすべてチュートリアルを読んで得たものです)、XCode と iOS の開発はまったくの初心者です。これまでのところ、iOS アプリの開発の基本は理解していますが、デリゲートがどのように機能するのか理解できないことが 1 つあります。デリゲートを使用する背後にある考え方は理解していますが、デリゲートを実装しようとするときに何が間違っているのかわかりません。カスタム デリゲートの実装方法を説明するために、小さな例 (シングル ビュー アプリケーション) を作成しました。何が間違っているのか教えていただければ幸いです。

XCode 4.5.2、ARC を有効にした iOS6.0 を使用しています。

この例では、単純な 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

上記の例の問題は、ビューのラベルに「AfterDelegate」と書きたい場所に「Before delegate」としか書かれていないことです。

すべての助けに感謝します。あけましておめでとう。

4

1 に答える 1

4

デリゲートをどこにも設定していないので、 になりますnilinitWithString: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.
于 2013-01-01T15:11:30.210 に答える