【发布时间】:2014-05-27 22:51:30
【问题描述】:
我对 Objective-c 很陌生,我的一些代码存在问题,我无法在 SO 或其他地方找到解决方案。感谢您的耐心等待。
基本上,我有一个模型类,它从我的服务器访问数据,以及两个视图控制器,它们充当模型的不同实例的委托,每个视图控制器都被分别分配为一个委托。
第一个视图控制器(ListViewController)只包含一个列表,数据加载正常。
第二个视图控制器(MapViewController)只包含一个地图。问题出在这里:
我在视图控制器的 viewDidLoad 方法中创建一个 URL 作为 NSString,并将它传递给该视图控制器使用的模型实例。在模型中,urlString 然后被转换为 NSURL,并启动连接/数据收集。没有从模型返回数据。
经过一些调试,我发现传入模型下载的 urlString 会保留它的类作为字符串,但是 jsonFileUrl 变量将具有 MapViewController 类,而不是 NSURL。
这是我的一些代码。
数据模型.h
#import <Foundation/Foundation.h>
@protocol DataModelProtocol <NSObject>
- (void)itemsDownloaded:(NSArray *)items;
@end
@interface DataModel : NSObject <NSURLConnectionDataDelegate>
@property (weak, nonatomic) id<DataModelProtocol> delegate;
- (void)downloadItems:(NSString *)urlString;
@end
数据模型.m
#import "DataModel.h"
#import "CustomClass.h"
@interface DataModel() {
NSMutableData *_downloadedData;
}
@end
@implementation DataModel
- (void)downloadItems:(NSString *)urlString {
//create url object with the link to download the json data
// THIS IS WHERE THE JSONFILEURL ENDS UP BECOMING MAPVIEWCONTROLLER CLASS
NSURL *jsonFileUrl = [NSURL URLWithString:urlString];
//create the url request
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:jsonFileUrl];
//create connection to the url
[NSURLConnection connectionWithRequest:urlRequest delegate:self];
}
... //functions to receive and parse results...
ListViewController.h
#import <UIKit/UIKit.h>
#import "DataModel.h"
@interface ListViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, DataModelProtocol>
@property (weak, nonatomic) IBOutlet UITableView *listOneTableView;
@property (weak, nonatomic) NSString *var1;
@property (weak, nonatomic) NSString *var2;
@end
ListViewController.m
#import "ListViewController.h"
#import "MapViewController.h"
#import "DataModel.h"
#import "CustomClass.h"
@interface ListViewController () {
DataModel *_dataModelInstance1; //data model to retrieve provider types
NSArray *_feedItems; //array for provider types
CustomClass *_selectedCustomInstance;
}
@end
@implementation ListViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//set this view controller as the delegate and data source for the table view
self.listOneTableView.delegate = self;
self.listOneTableView.dataSource = self;
//initialize an array object assigned to the pointer _feedItems
_feedItems = [[NSArray alloc] init];
//create a new data model and assign it to _providerTypeDataModel
_dataModelInstance1 = [[DataModel alloc] init];
//set this view controller as the delegate for the _providerTypeDataModel object
_dataModelInstance1.delegate = self;
//call the downloadItems method of the _providerTypeDataModel object
// this will have the model download the data and organize it for us. afterwards, we need to handle it through the itemsDownloaded function
NSString *downloadURL = [NSString stringWithFormat:@"http://www....com/phpfile.php?var1=%@&var2=%@", self.var1, self.var2];
[_dataModelInstance1 downloadItems:downloadURL]; //THIS ONE WORKS FINE
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)itemsDownloaded:(NSArray *)items {
_feedItems = items;
[self.listOneTableView reloadData];
}
...//delegate methods and segue to MapViewController which passes var1, var2, and _selectedCustomInstance
MapViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import "DataModel.h"
#import "CustomClass.h"
@interface MapViewController : UIViewController <DataModelProtocol>
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@property (weak, nonatomic) NSString *var1;
@property (weak, nonatomic) NSString *var2;
@property (weak, nonatomic) NSString *selectedCustomInstance;
@end
MapViewController.m
#import "MapViewController.h"
#import "DataModel.h"
#import "CustomClass.h"
@interface MapViewController () {
DataModel *_dataModelInstance2;
NSArray *_returnedArray;
}
@end
@implementation MapViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//initialize array for the provider list
_returnedArray = [[NSArray alloc] init];
//create new datamodel for the provider list
_dataModelInstance2 = [[DataModel alloc] init];
//set this view controller as the delegate for the datamodel object
_dataModelInstance2.delegate = self;
//THIS STRING IS CREATED ACCURATELY, AND WHEN TESTED INDEPENDENTLY IN THE BROWSER, RETURNS THE DESIRED JSON
NSString *downloadURL = [NSString stringWithFormat:@"http://www.....com/phpfile2.php?var1=%@&var2=%@&var3=%@", self.var1, self.var2, self.selectedCustomInstance];
//THIS MODEL METHOD GETS CALLED, AND THE NSSTRING IS PASSED, BUT SUBSEQUENT CONVERSION TO NSURL RESULTS INSTEAD IN A MODELVIEWCONTROLLER CLASS OBJECT
[_dataModelInstance2 downloadItems:downloadURL];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)itemsDownloaded:(NSArray *)items {
_returnedArray = items;
}
@end
【问题讨论】:
-
是在分配
jsonFileURL之后立即发生不需要的转换,还是仅在返回结果时发生?如果是后者,我认为我们需要看看结果在 DataModel 中是如何解析的,才能给出完整的答案 -
DataModel.m将是几乎可以肯定存在问题的文件。它是实际下载数据的NSURLConnection的委托,而您未能包含此类应具有的任何NSURLConnectionDelegate方法。 -
由于您没有向我们提供您尝试使用的实际 URL,它们之间有什么区别?某些东西可能编码不正确。
标签: ios objective-c nsurlconnection nsurl