2012-03-21 3 views
0

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

Любые идеи о том, что я могу сделать, чтобы вызвать метод делегата перед 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; 
} 

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

+0

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

ответ

1

Я думаю, что вы можете быть немного смущены тем, что используется 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

Если вам нужно передать эту строку на этапе инициализации, вы можете передать ее в методе 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]; 
} 
0

Можете ли вы создать пользовательский инициализатор для 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

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

В 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

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

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

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

+0

Метод dealloc вызывается так, что представление создается каждый раз, когда оно загружается, и данные передаются правильно. – Vikings

+0

Я не хочу использовать MVC, потому что его только один объект получает. Похоже, что для моего проекта слишком много. – Vikings

Смежные вопросы