Iphone 将数据从NSObject发送到UIViewController

Iphone 将数据从NSObject发送到UIViewController,iphone,ios,delegates,protocols,Iphone,Ios,Delegates,Protocols,我已经研究这个问题将近4天了 我认为这不是我的代码的问题,而是引起问题的应用程序的结构 我正在尝试实现协议和委托,以将数组从一个NSObject(类)获取到一个ViewController 我的代码几乎是逐行复制而来的。唯一的区别在于我打开的面,因此不得不将(非原子,保留)替换为(强),并且没有使用dealloc:) 尽管如此,它仍然没有将数据传回viewcontroller。(非常烦人)我尝试了几十种不同的解决方案组合,但都没有奏效。这让我相信,我的应用程序的结构或初始化方式可能存在错误,我现

我已经研究这个问题将近4天了

我认为这不是我的代码的问题,而是引起问题的应用程序的结构

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

我的代码几乎是逐行复制而来的。唯一的区别在于我打开的面,因此不得不将(非原子,保留)替换为(强),并且没有使用dealloc:)

尽管如此,它仍然没有将数据传回viewcontroller。(非常烦人)我尝试了几十种不同的解决方案组合,但都没有奏效。这让我相信,我的应用程序的结构或初始化方式可能存在错误,我现在将尝试解释一下

当带有tableview的viewcontroller加载名为parser类委托的viewdidload方法时,tableview的第一个单元格加载后,它将调用我的连接类,并告诉它从服务器下载一些数据。 在我的connection类中,我使用apple库中的NSURLConnection委托,在委托方法ConnectionDiFinishLoading中,下载的数据被传递到我的解析器类(然而,我认为这是出错的地方,因为我再次声明了对象..我认为这就是出错的地方)

这就是我从连接类调用解析器类的方式

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;
//..
@protocol PassParsedData
- (void)sendArray:(NSArray *)array;
@end

//..
id <PassParsedData> mydelegate;
//..
@property (strong) id  <PassParsedData> mydelegate; 
#import "EngineResponses.h" //delegates & protocols

interface SearchViewController : UITableViewController <PassParsedData> {

//delegates to parser class
    EngineResponses *engineResponses;

    EngineRequests *engineRequests;  
//..
EngineResponses *engineResponses;
@protocol PassParsedData
- (void)sendArray:(NSArray *)array;
@end

//..
id <PassParsedData> mydelegate;
//..
@property (strong) id  <PassParsedData> mydelegate; 
EngineRequests.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]; 
}
//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];
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
//..
    [[self mydelegate]sendArray:filteredArray];    
}
#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]; 
}
@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];
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
//..
    [[self mydelegate]sendArray:filteredArray];    
}
引擎响应。h

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

interface SearchViewController : UITableViewController <PassParsedData> {

//delegates to parser class
    EngineResponses *engineResponses;
//..
@protocol PassParsedData
- (void)sendArray:(NSArray *)array;
@end

//..
id <PassParsedData> mydelegate;
//..
@property (strong) id  <PassParsedData> mydelegate; 
#import "EngineResponses.h" //delegates & protocols

interface SearchViewController : UITableViewController <PassParsedData> {

//delegates to parser class
    EngineResponses *engineResponses;

    EngineRequests *engineRequests;  
//..
EngineResponses *engineResponses;
@protocol PassParsedData
- (void)sendArray:(NSArray *)array;
@end

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

1好的。我将根据您更新的代码重新执行此操作。为了方便起见,我复制了您的代码并进行了修改

ViewController.h

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

interface SearchViewController : UITableViewController <PassParsedData> {

//delegates to parser class
    EngineResponses *engineResponses;
//..
@protocol PassParsedData
- (void)sendArray:(NSArray *)array;
@end

//..
id <PassParsedData> mydelegate;
//..
@property (strong) id  <PassParsedData> mydelegate; 
#import "EngineResponses.h" //delegates & protocols

interface SearchViewController : UITableViewController <PassParsedData> {

//delegates to parser class
    EngineResponses *engineResponses;

    EngineRequests *engineRequests;  
//..
EngineResponses *engineResponses;
@protocol PassParsedData
- (void)sendArray:(NSArray *)array;
@end

//..
id <PassParsedData> mydelegate;
//..
@property (strong) id  <PassParsedData> mydelegate; 
说明:EngineRequests现在是一个实例变量,不应在本地重新定义。 您可以在本地定义一个相同名称的变量,该变量将隐藏实例变量。我想 在这种情况下,您会得到一个编译器警告,但这会起作用,并且很可能会让您感到困惑。 同样,如果您一次使用多个请求,那么此解决方案将不起作用

引擎请求.h

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

interface SearchViewController : UITableViewController <PassParsedData> {

//delegates to parser class
    EngineResponses *engineResponses;
//..
@protocol PassParsedData
- (void)sendArray:(NSArray *)array;
@end

//..
id <PassParsedData> mydelegate;
//..
@property (strong) id  <PassParsedData> mydelegate; 
#import "EngineResponses.h" //delegates & protocols

interface SearchViewController : UITableViewController <PassParsedData> {

//delegates to parser class
    EngineResponses *engineResponses;

    EngineRequests *engineRequests;  
//..
EngineResponses *engineResponses;
@protocol PassParsedData
- (void)sendArray:(NSArray *)array;
@end

//..
id <PassParsedData> mydelegate;
//..
@property (strong) id  <PassParsedData> mydelegate; 
EngineRequests.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]; 
}
//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];
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
//..
    [[self mydelegate]sendArray:filteredArray];    
}
#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]; 
}
@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];
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
//..
    [[self mydelegate]sendArray:filteredArray];    
}
说明:这里对EngineResponses的引用现在也是一个实例变量,而不是本地定义的变量。对象不会是新创建的,但它引用了在视图控制器中创建的对象。这是EngineResponse“知道”其视图控制器对象的一个,因此可以传回解析的数据

引擎响应。h

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

interface SearchViewController : UITableViewController <PassParsedData> {

//delegates to parser class
    EngineResponses *engineResponses;
//..
@protocol PassParsedData
- (void)sendArray:(NSArray *)array;
@end

//..
id <PassParsedData> mydelegate;
//..
@property (strong) id  <PassParsedData> mydelegate; 
#import "EngineResponses.h" //delegates & protocols

interface SearchViewController : UITableViewController <PassParsedData> {

//delegates to parser class
    EngineResponses *engineResponses;

    EngineRequests *engineRequests;  
//..
EngineResponses *engineResponses;
@protocol PassParsedData
- (void)sendArray:(NSArray *)array;
@end

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

。。。试试看:)

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

ViewController.h

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

interface SearchViewController : UITableViewController <PassParsedData> {

//delegates to parser class
    EngineResponses *engineResponses;
//..
@protocol PassParsedData
- (void)sendArray:(NSArray *)array;
@end

//..
id <PassParsedData> mydelegate;
//..
@property (strong) id  <PassParsedData> mydelegate; 
#import "EngineResponses.h" //delegates & protocols

interface SearchViewController : UITableViewController <PassParsedData> {

//delegates to parser class
    EngineResponses *engineResponses;

    EngineRequests *engineRequests;  
//..
EngineResponses *engineResponses;
@protocol PassParsedData
- (void)sendArray:(NSArray *)array;
@end

//..
id <PassParsedData> mydelegate;
//..
@property (strong) id  <PassParsedData> mydelegate; 
说明:EngineRequests现在是一个实例变量,不应在本地重新定义。 您可以在本地定义一个相同名称的变量,该变量将隐藏实例变量。我想 在这种情况下,您会得到一个编译器警告,但这会起作用,并且很可能会让您感到困惑。 同样,如果您一次使用多个请求,那么此解决方案将不起作用

引擎请求.h

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

interface SearchViewController : UITableViewController <PassParsedData> {

//delegates to parser class
    EngineResponses *engineResponses;
//..
@protocol PassParsedData
- (void)sendArray:(NSArray *)array;
@end

//..
id <PassParsedData> mydelegate;
//..
@property (strong) id  <PassParsedData> mydelegate; 
#import "EngineResponses.h" //delegates & protocols

interface SearchViewController : UITableViewController <PassParsedData> {

//delegates to parser class
    EngineResponses *engineResponses;

    EngineRequests *engineRequests;  
//..
EngineResponses *engineResponses;
@protocol PassParsedData
- (void)sendArray:(NSArray *)array;
@end

//..
id <PassParsedData> mydelegate;
//..
@property (strong) id  <PassParsedData> mydelegate; 
EngineRequests.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]; 
}
//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];
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
//..
    [[self mydelegate]sendArray:filteredArray];    
}
#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]; 
}
@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];
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
//..
    [[self mydelegate]sendArray:filteredArray];    
}
说明:这里对EngineResponses的引用现在也是一个实例变量,而不是本地定义的变量。对象不会是新创建的,但它引用了在视图控制器中创建的对象。这是EngineResponse“知道”其视图控制器对象的一个,因此可以传回解析的数据

引擎响应。h

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

interface SearchViewController : UITableViewController <PassParsedData> {

//delegates to parser class
    EngineResponses *engineResponses;
//..
@protocol PassParsedData
- (void)sendArray:(NSArray *)array;
@end

//..
id <PassParsedData> mydelegate;
//..
@property (strong) id  <PassParsedData> mydelegate; 
#import "EngineResponses.h" //delegates & protocols

interface SearchViewController : UITableViewController <PassParsedData> {

//delegates to parser class
    EngineResponses *engineResponses;

    EngineRequests *engineRequests;  
//..
EngineResponses *engineResponses;
@protocol PassParsedData
- (void)sendArray:(NSArray *)array;
@end

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

。。。试试看:)

始终检查零对象。向nil对象发送消息将不起任何作用,您的应用程序将继续。我敢打赌这就是问题所在,因为您在各地都进行了本地分配。为什么不将receivedata方法改为静态方法呢?因为在某些计算和解析过程中,似乎不需要这些类。那么零对象将不是一个因素。

始终检查零对象。向nil对象发送消息将不起任何作用,您的应用程序将继续。我敢打赌这就是问题所在,因为您在各地都进行了本地分配。为什么不将receivedata方法改为静态方法呢?因为在某些计算和解析过程中,似乎不需要这些类。那么零对象就不是一个因素。

你的代码的编辑版本比散文描述更容易诊断。嗯,你在做类似于
[myParser setDelegate:myViewController]的事情吗?此外,我还需要查看您的代码以提出更好的解决方案。好的,我已经用我的代码进行了更新。。对不起,花了这么长时间,只是确保我把所有东西都准备好了。。所以我认为错误在于我在两个地方分配解析器对象。。。但是我不确定这是否正确,或者如何解决它。那么,你的“文件名”和你的类名匹配吗?或者ParserClass是你的引擎响应?似乎是这样。如果是这样的话,那么你会无缘无故地分配两次。在ConnectiondFinish中,您创建了一个新的。现在它的mydelegate最初设置为nil(我猜)。因此,当您向mydelegate发送sendArray消息时,它是nil,然后向nil对象发送消息。这既不会导致编译器错误,也不会导致运行时错误,但肯定不会执行sendArray方法。确保您的连接类