将数据从NSObject发送到UIViewController

时间:2012-03-14 23:04:33

标签: iphone ios delegates protocols

我已经在这个问题上工作了近4天了。

我认为我的代码不是问题,而是导致问题的应用程序结构。

我正在尝试实现协议和委托,以便从一个NSObject(类)到一​​个ViewController获取一个数组。

我的代码几乎是从这个tutorial一行一行地复制了,唯一的区别在于我已经开启ARC,所以不得不替换(非原子,保留)到(强)并且没有使用dealloc :)

所以说它仍然没有将数据传递回viewcontroller。 (非常讨厌)我已经尝试了几十种不同的解决方案组合,我已经帮助过,没有任何工作。这让我相信可能在我的应用程序结构或事物初始化方式等方面存在错误,我现在将尝试解释。

当我的带有tableview的viewcontroller加载了名为我的解析器类的委托的viewdidload方法时,一旦tableview的第一个单元加载了它,就调用了我的连接类,并告诉它从服务器下载一些数据。 在我的连接类中,我使用来自apple库的NSURLConnection委托,在委托方法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.m

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

1

2 个答案:

答案 0 :(得分:1)

奥莱特。我会根据您更新的代码重新执行此操作。为方便起见,我复制您的代码并进行修改。

<强> 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现在是一个可变的实例,不应在本地重新定义。 您可以在本地定义一个同名的变量,这将隐藏实例变量。我认为 在这种情况下,你得到一个编译器警告,但这将工作,很可能会让你感到困惑。 同样,如果您一次使用多个请求,则此解决方案将无效!

<强> 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];    
}

...试一试:)

答案 1 :(得分:0)

始终检查nil对象。向nil对象发送消息将不执行任何操作,您的应用将继续。我打赌这是问题,因为你在本地分配到处都是。为什么不把receivedata方法变成静态方法,因为看起来你不需要这些类来进行一些计算和解析。那么零物不会是一个因素。

相关问题