Передача данных делегатом по протоколу iPhone - PullRequest
0 голосов
/ 22 марта 2012

Я передаю строку через делегата и протокол.Строка поступает в класс правильно, но это происходит после вызова метода viewDidLoad.Метод viewDidLoad нуждается в той передаваемой строке.

Есть какие-либо идеи о том, что я могу сделать, чтобы метод делегата был вызван перед viewDidLoad?Я думал, что это была идея передачи данных делегата / протокола.

Метод, при котором создается и отправляется новое представление:

ViewControllerTwo *two = [[ViewControllerTwo alloc] initWithNibName:@"ViewControllerTwo" bundle:nil];
two.delegate = self;
[two setString:theString];
[self.navigationController pushViewController:two animated:YES];
[two release]; 

В ViewControllerTwo:

- (void)setString:(NSString *)str
{
    self.myString = str;
}

Изменить: Спасибо за вклад.Тем не менее, я понимаю, как передать эти данные через метод init.В последнее время я тестировал протоколы и делегатов и хотел посмотреть, есть ли способ сделать это.Я успешно передал такие данные в другом классе, и это сработало.Метод протокола был вызван сначала установив строку.Это казалось более чистым способом обработки передаваемых данных.

Ответы [ 5 ]

1 голос
/ 22 марта 2012

Я думаю, вы можете быть немного озадачены тем, для чего используется Delegation и почему.

Например, вы можете захотеть создать протокол в подклассе UIViewController, если вы выполняли какое-то действие в этом ViewController и вам нужно было сообщить другому подклассу, что это действие или результат этого действие.

Теперь для того, чтобы подкласс, который хочет знать о действии (получатель), должен соответствовать этому протоколу в своем заголовочном файле.

Вы также должны «установить» delegate на receiving class/controller.

Есть много способов получить ссылку на receiving controller/class, чтобы установить его как delegate, но распространенной ошибкой является выделение и инициализация нового экземпляра этого класса для установки его в качестве делегата, когда этот класс уже имеет был создан. То, что это делает, устанавливает вновь созданный класс в качестве делегата вместо класса, который уже был создан и ожидает сообщения.

Что вы пытаетесь сделать, это просто передать значение Вновь созданному классу. Поскольку вы только что создали этот класс UIViewController, все, что для этого необходимо, - это свойство в receiver(ViewControllerTwo).

В вашем случае NSString:

 @Property (nonatiomic, retain) NSString *string; //goes in ViewControllerTwo.h

и, конечно, не забудьте в основном:

  @synthesize string; //Goes in ViewControllerTwo.m

Теперь в вашем ViewControllerTwo.

нет необходимости устанавливать сеттер.
 - (void)setString:(NSString *)str  //This Method can be erased
    {                                  //The setter is created for free
        self.myString = str;          // when you synthesized the property
    }   

Сеттер и геттеры свободны при использовании @synthesize. Просто передайте значение в ViewController. Реализация идентична вашему коду за исключением делегата:

  ViewControllerTwo *two = [[ViewControllerTwo alloc] initWithNibName:@"ViewControllerTwo" bundle:nil];
    [two setString:theString];
    [self.navigationController pushViewController:two animated:YES];
    [two release];
0 голосов
/ 22 марта 2012

Размещение данных в методе init или viewDidLoad не будет работать, потому что пользователи могут переключаться назад и вперед без выгрузки представления или повторной инициализации контроллера представления.

Лучшее место для извлечения измененных данных - этометод контроллера viewWillAppear.Таким образом, данные будут обновляться каждый раз, когда пользователь переключается.

Другой лучший способ - использование архитектуры MVC.Если у вас есть отдельный класс модели, который будет просто хранить данные, и вы можете записывать / обновлять данные с любого контроллера.

0 голосов
/ 22 марта 2012

Можете ли вы создать собственный инициализатор для ViewControllerTwo, например,

- (id)initWithString:(NSString *)aString;
{
    self = [super initWithNibName:@"ViewControllerTwo" bundle:nil];
    if( !self ) return nil;

    self.myString = aString;
    // other initialization

    return self;
}

Ваша инициализация в ViewControllerOne будет просто:

ViewControllerTwo *vc = [[ViewControllerTwo alloc] initWithString:theString];
[[self navigationController] pushViewController:vc animated:YES];
[vc release];
0 голосов
/ 22 марта 2012

Я бы не использовал протокол для этого. Чтобы передать данные из родительского контроллера представления в дочерний, используйте пользовательский метод инициализатора.

В ViewControllerTwo.h:

-(id)initWithString:(NSString *)str;

А затем внедрите это в свой ViewControllerTwo.m:

-(id)initWithString:(NSString *)str {
    self = [super self];
    if(self) {
        self.myString = str;
    }
    return self;

А затем вызвать это в вашем ViewController один:

ViewControllerTwo *two = [[ViewControllerTwo alloc] initWithString:@"Cool String"];
0 голосов
/ 22 марта 2012

если вам нужно передать эту строку на этапе инициализации, вы можете передать ее в методе init.

Таким образом, в вашем контроллере вам нужно создать свойство и дополнительный метод init, такой как:

.h

@property (nonatomic, copy) NSString* myString;

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

.m

@synthesize myString;

-(id)initWithString:(NSString*)theString {
    self = [super initWithNibName:@"ViewController" bundle:nil]; // I prefer to set the name of the controller internally
    if(self) {
        myString = [theString copy];
    }
    return self;
}

затем используйте self.myString где хотите.

Если вы не используете ARC,не забудьте освободить.

- (void)dealloc
{
   [myString release];
   [super dealloc];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...