Отправка данных из NSObject в UIViewController - PullRequest
1 голос
/ 15 марта 2012

Я работаю над этой проблемой уже почти 4 дня.

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

Я пытаюсь реализовать протоколы и делегатов.чтобы получить массив из одного NSObject (класса) в ViewController.

мой код в значительной степени построчно скопирован из этого учебника единственные различия заключаются в том, что у меня включена ARCпоэтому пришлось заменить (nonatomic, retain) на (strong) и не использовать dealloc:)

, поэтому при этом говорится, что данные по-прежнему не передаются обратно в viewcontroller.(очень раздражает) Я перепробовал десятки различных комбинаций решений, с которыми мне помогли, и ничего не помогло.Это заставило меня поверить, что, возможно, есть ошибка в структуре моего приложения или в способе инициализации и т. Д., Который я сейчас попытаюсь объяснить.

Когда мой viewcontroller с tableview загружает метод viewdidloadвызвал делегат моего класса синтаксического анализатора, затем, как только первая ячейка табличного представления загрузилась, он вызвал мой класс соединения и сказал ему загрузить некоторые данные с сервера.Внутри моего класса соединения я использую делегаты NSURLConnection из библиотеки apple, в методе делегата connectionDidFinishLoading загруженные данные передаются в мой класс синтаксического анализатора (однако я думаю, что это происходит неправильно, потому что я снова объявляю объект .. которыйя думаю, что все идет не так, как надо)

это то, как я вызываю свой класс синтаксического анализатора из своего класса соединения.

parserClass *myparser = [[EngineResponses alloc] init];
[myparser  ReciveResponse:receivedData];

затем, когда данные попадают в мой класс синтаксического анализатора, они анализируются изатем я пытаюсь передать данные моему viewcontroller ... но он никогда не получает доступ к тому методу делегата, который я настроил.

Надеюсь, в этом проблема, потому что я просто не знаю, где еще я ошибаюсь.как вы думаете?

ОБНОВЛЕНИЕ: вот мой код -

ViewController.h

#import "EngineResponses.h" //delegates & protocols

interface SearchViewController : UITableViewController <PassParsedData> {

//delegates to parser class
    EngineResponses *engineResponses;
//..

ViewController.m

#import "EngineResponses.h"

//this is where I set up the delegate/protocol for the parser class
- (void)viewDidLoad
{
    [super viewDidLoad];

//..
engineResponses = [[EngineResponses alloc] init];
[engineResponses setMydelegate:self];
//..
}

//this is where i set up and call the connection class
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//..
if(indexPath.section == 0){        
    //..
    if (indexPath.row == 0){
     EngineRequests *engineRequests = [[EngineRequests alloc] init];
                [engineRequests initalizePacketVariables:0 startCode:@"myReg" activationCode:@"myAct" methodName:@"GetStuff"];
                //..
}

#pragma - Reciver methods

- (void)sendArray:(NSArray *)array
{
    ICMfgFilterArray = array;
    [self.tableView reloadData]; 
}

EngineRequests.m

//connection delegates etc..
//then I pass the data from the connection delegates over to the parser class
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{   
    EngineResponses *engineResponses = [[EngineResponses alloc] init];
    [engineResponses  ReciveResponse:receivedData];
}

EngineResponses.h

@protocol PassParsedData
- (void)sendArray:(NSArray *)array;
@end

//..
id <PassParsedData> mydelegate;
//..
@property (strong) id  <PassParsedData> mydelegate; 

EngineResponses.м

- (void)parserDidEndDocument:(NSXMLParser *)parser
{
//..
    [[self mydelegate]sendArray:filteredArray];    
}

1

Ответы [ 2 ]

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

Allright. Я сделаю это заново на основе вашего обновленного кода. Чтобы было проще, я копирую ваш код и делаю изменения.

ViewController.h

#import "EngineResponses.h" //delegates & protocols

interface SearchViewController : UITableViewController <PassParsedData> {

//delegates to parser class
    EngineResponses *engineResponses;

    EngineRequests *engineRequests;  
//..

Пояснение: Вы используете ARC. Если вы определяете указатель локально, как вы делали раньше, и не сохранить его - что вы не можете из-за ARC - тогда он будет выпущен сразу после его создание. Вам нужно будет сохранить хотя бы одну ссылку на объект. Имейте в виду, что ARC означает автоматический подсчет ссылок. Как только нет ссылка на объект будет освобождена. Это предложение с определенным здесь объектом engineRequests работает только тогда, когда вы отправляйте только один запрос за раз. Если у вас есть несколько запросов, то есть для более чем одной ячейки или в любом случае, вы можете использовать изменяемый массив или изменяемый словарь, в котором вы сохраняете запросы, пока используете их.

ViewController.m

#import "EngineResponses.h"

//this is where I set up the delegate/protocol for the parser class
- (void)viewDidLoad
{
    [super viewDidLoad];

//..
engineResponses = [[EngineResponses alloc] init];
[engineResponses setMydelegate:self];

engineRequests = [[EngineRequests alloc] init];  // Use instance variable instead of local variable
[engineRequests setEnineResponses:engineResponses];

//..
}

//this is where i set up and call the connection class
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//..
if(indexPath.section == 0){        
    //..
    if (indexPath.row == 0){
     [engineRequests initalizePacketVariables:0 startCode:@"myReg" activationCode:@"myAct" methodName:@"GetStuff"];
                //..
}

#pragma - Reciver methods

- (void)sendArray:(NSArray *)array
{
    ICMfgFilterArray = array;
    [self.tableView reloadData]; 
}

Объяснение: engineRequets теперь является экземпляром varaible и не должен переопределяться локально. Вы можете определить переменную с тем же именем локально, которая будет скрывать переменную экземпляра. Я думаю в этом случае вы получите предупреждение компилятора, но это сработает и, скорее всего, вас запутает. Опять же, если вы используете более одного запроса одновременно, то это решение не будет работать!

EngineRequests.h

EngineResponses *engineResponses;

EngineRequests.m

@synthesize engineResponses;

//connection delegates etc..
//then I pass the data from the connection delegates over to the parser class
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{   
    //EngineResponses *engineResponses = [[EngineResponses alloc] init]; //This Object has already been created! 
    [engineResponses  ReciveResponse:receivedData];
}

Объяснение: Здесь также ссылка на EngineResponses теперь является переменной экземпляра, а не локально определенной. Объект не будет вновь создан, но он ссылается на тот самый объект, который был создан в контроллере представления. Это тот EngineResponses, который «знает» свой объект контроллера представления и поэтому может передавать проанализированные данные.

EngineResponses.h

@protocol PassParsedData
- (void)sendArray:(NSArray *)array;
@end

//..
id <PassParsedData> mydelegate;
//..
@property (strong) id  <PassParsedData> mydelegate; 

EngineResponses.m

- (void)parserDidEndDocument:(NSXMLParser *)parser
{
//..
    [[self mydelegate]sendArray:filteredArray];    
}

... попробуй :)

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

Всегда проверяйте, нет ли объектов.Отправка сообщения нулевому объекту ничего не изменит, и ваше приложение продолжит работу.Могу поспорить, что это проблема, так как вы локально распределяете повсюду.Почему бы вам не сделать метод receiveata статическим методом, поскольку, похоже, вам не нужны эти классы более чем на несколько секунд для некоторых вычислений и анализа.Тогда ноль объектов не будет фактором.

...