【问题标题】:String passed to data model from delegate results in object with delegate's class从委托传递给数据模型的字符串会产生具有委托类的对象
【发布时间】: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


【解决方案1】:

这是一种猜测,因为我们的信息不完整,但似乎它工作的实例和它不工作的实例之间的唯一区别是 URL 的实际形式。这让我相信这是一个编码问题,因为您没有对字符串进行编码。

尝试在downloadItems:(NSString *)urlString; 的第一行添加以下行:

urlString = [urlString sstringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];

【讨论】:

    猜你喜欢
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多