iphone - 将数据从 NSObject 发送到 UIViewController

标签 iphone ios delegates protocols

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

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

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

我的代码几乎是从 tutorial 中逐行复制的唯一的区别在于我打开了 ARC,所以不得不将 (nonatomic, retain) 替换为 (strong) 并且没有使用 dealloc :)

所以话虽如此,它仍然没有将数据传回 View Controller 。 (非常烦人)我已经尝试了几十种不同的解决方案组合,但都没有奏效。这让我相信我的应用程序的结构或初始化方式等可能存在错误,我现在将尝试对此进行解释。

当我的 viewcontroller 和 tableview 加载 viewdidload 方法调用我的解析器类的委托(delegate)时,一旦 tableview 的第一个单元格加载它调用我的连接类并告诉它从服务器下载一些数据。 在我的连接类中,我使用来自苹果库的 NSURLConnection 委托(delegate),在委托(delegate)方法 connectionDidFinishLoading 中,已下载的数据被传递到我的解析器类(但是我​​认为这是错误的地方,因为我再次声明了对象..我认为事情出了问题)

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

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

一旦数据在我的解析器类中,它就会被解析,然后我尝试将数据传递到我的 View Controller ..但它永远不会访问我设置的委托(delegate)方法。

希望这就是问题所在,因为我只是不知道还有哪里出错了。 你怎么看?

更新:这是我的代码 -

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

最佳答案

好的。我会根据你更新的代码重新做。为了方便起见,我复制了您的代码并进行了修改。

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 的引用现在也是一个实例变量,而不是本地定义的变量。该对象不会被新创建,但它引用了在 View Controller 中创建的那个对象。这是一个“知道”其 View Controller 对象并因此可以传回已解析数据的 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];    
}

...试一试:)

关于iphone - 将数据从 NSObject 发送到 UIViewController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9711649/

相关文章:

ios - 如何在 UIViewController 中对 UICollectionView 进行单元测试

iphone - UIImageView 边框颜色

iphone - URL连接连接超时时iPhone应用程序崩溃

ios - UIScrollView 弹回来

c# - 为什么这两个函数不返回相同的值?

ios - ObjC : memory usage of delegate vs block?

c# - 任何方法类型的委托(delegate) - C#

ios - Uitableview 与 UICollectionviewcell 和 UITableviewcell

从多任务托盘中删除后 iPhone 应用程序卡住

ios - 如何将可选的 UIImage 附加到数组