我知道这是一个愚蠢的问题,但我无法找到解决方案。
这是我的代码:
ConnectionService.h。
#import "LaunchScreenViewController.h"
@interface ConnectionService : NSObject
-(void)getsFeaturedProducts;
@end
ConnectionService.m
-(void)getsFeaturedProducts {
NSString *urlString = [NSString stringWithFormat:@"my-url",[[AppDelegate instance] getUrl]];
NSURL *url = [NSURL URLWithString:urlString];
NSURLSessionDataTask *getData = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData* data, NSURLResponse *response, NSError* error){
NSString* rawJson = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *value = [rawJson JSONValue];
_featuredProducts = [[NSDictionary alloc]initWithDictionary:value];
NSLog(@"Featured products: %@", _featuredProducts);//not empty
LaunchScreenViewController *lsvc = [[LaunchScreenViewController alloc]init];
lsvc.featuredProducts = self.featuredProducts;
NSLog(@"Featured products: %@", lsvc.featuredProducts);//not empty
}];
[getData resume];
}
LaunchScreenViewController.h
#import "ConnectionService.h"
@interface LaunchScreenViewController : UIViewController
@property(nonatomic,strong) NSDictionary *featuredProducts;
@end
LaunchScreenViewController.m
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:YES];
ConnectionService *connectionService = [[ConnectionService alloc]init];
[connectionService refreshProducts];
self.featuredProducts = [[NSDictionary alloc]init];
NSLog(@"featuredProducts: %@", self.featuredProducts);//empty
NSArray *keys = [[NSArray alloc]initWithArray:[self.featuredProducts allKeys]];
NSLog(@"All featured product keys: %@", keys);
}
我做错了什么?
P.S。编程目标-c少于一个月,所以是的...谢谢-rep。
答案 0 :(得分:1)
你认为这个异步问题是错误的 - 但你并不遥远。以下是您的代码现在正在做的事情:
创建了一个LaunchScreenViewController实例。
LaunchScreenViewController的实例创建了ConnectionService的实例
ConnectionService查询异步数据
返回数据后,它会创建LaunchScreenViewController的 BRAND NEW 实例并将其传递给数据。
您检查原始的LaunchScreenViewController是否有数据,但没有 - 它转而使用新实例。
您希望将数据传回原始的LaunchScreenViewController。有几种方法可以做到这一点。我会告诉你一个并链接到第二个。
让我们举例说明如何通过NSNotificationCenter将数据传回原始控制器:
LaunchScreenViewController.m
- (void)viewDidLoad:(BOOL)animated{
//Your current code....
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(receiveConnectionData:)
name:@"ConnectionDataReceived"
object:nil];
}
- (void) receiveTestNotification:(NSNotification *) notification
{
// [notification name] should always be @"ConnectionDataReceived"
// unless you use this method for observation of other notifications
// as well.
if ([[notification name] isEqualToString:@"ConnectionDataReceived"]){
self.featuredProducts = [[NSDictionary alloc]init];
NSLog(@"featuredProducts: %@", self.featuredProducts);//empty
NSArray *
NSArray *keys = [[NSArray alloc]initWithArray:[notification.object allKeys]];
NSLog(@"All featured product keys: %@", keys);
NSLog (@"Successfully received the test notification!");
}
}
在您的ConnectionService.h
中-(void)getsFeaturedProducts {
NSString *urlString = [NSString stringWithFormat:@"my-url",[[AppDelegate instance] getUrl]];
NSURL *url = [NSURL URLWithString:urlString];
NSURLSessionDataTask *getData = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData* data, NSURLResponse *response, NSError* error){
NSString* rawJson = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *value = [rawJson JSONValue];
_featuredProducts = [[NSDictionary alloc]initWithDictionary:value];
NSLog(@"Featured products: %@", _featuredProducts);//not empty
//Pass the NSDictionary back to the ORIGINAL LaunchViewController
[[NSNotificationCenter defaultCenter] postNotificationName:@"ConnectionDataReceived" _featuredProducts];
}];
[getData resume];
}
注意:您也可以使用Delegate来完成此操作,这更复杂但更强大。你可以在这里找到Chris Mills的一个很好的教程:https://coderchrismills.wordpress.com/2011/05/05/basic-delegate-example/
答案 1 :(得分:0)
您需要将结果返回给控制器。
您需要做的是在您的 - (void)getsFeaturedProducts函数中添加一个完成块,然后在返回结果后立即调用它传回结果。
在同一个功能中,您可以使用正确的数据重新加载视图。
<强>服务强>:
PYSPARK_PYTHON
<强>控制器强>:
-(void)getsFeaturedProducts:(void (^)(NSDictionary *featuredProducts))completionHandler {
NSString *urlString = [NSString stringWithFormat:@"my-url",[[AppDelegate instance] getUrl]];
NSURL *url = [NSURL URLWithString:urlString];
NSURLSessionDataTask *getData = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData* data, NSURLResponse *response, NSError* error){
NSString* rawJson = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *featuredProducts = [rawJson JSONValue];
completionHandler(featuredProducts);
}];
[getData resume];
}
}
答案 2 :(得分:0)
您的代码无效,因为使用LaunchScreenViewController
创建的alloc init
实例不是在Storyboard / XIB文件中创建的实例。
从另一个类异步检索数据的推荐方法是完成处理程序。
在 ConnectionService.m 中使用完成处理程序实现该方法,并在.h文件中相应地声明它。
- (void)getsFeaturedProductsWithCompletion:(void (^)(NSDictionary *products))completion
{
NSString *urlString = [NSString stringWithFormat:@"my-url",[[AppDelegate instance] getUrl]];
NSURL *url = [NSURL URLWithString:urlString];
NSURLSessionDataTask *getData = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData* data, NSURLResponse *response, NSError* error){
NSString* rawJson = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *value = [rawJson JSONValue];
completion(value);
}];
[getData resume];
}
附注:强烈建议在数据任务中添加错误处理!!
在 LaunchScreenViewController.h 中声明ConnectionService
实例的属性
#import "ConnectionService.h"
@interface LaunchScreenViewController : UIViewController
@property(nonatomic,strong) NSDictionary *featuredProducts;
@property(nonatomic,strong) ConnectionService *connectionService;
@end
在 LaunchScreenViewController.m 中调用方法
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:YES];
connectionService = [[ConnectionService alloc]init];
[connectionService getsFeaturedProductsWithCompletion:^(NSDictionary *products) {
self.featuredProducts = products;
NSLog(@"featuredProducts: %@", self.featuredProducts);//empty
NSArray *keys = [[NSArray alloc]initWithArray:[self.featuredProducts allKeys]];
NSLog(@"All featured product keys: %@", keys);
connectionService = nil; // release the connectionService instance if needed
}];
}
答案 3 :(得分:-1)
-(void)getsFeaturedProducts {
NSString *urlString = [NSString stringWithFormat:@"my-url",[[AppDelegate instance] getUrl]];
NSURL *url = [NSURL URLWithString:urlString];
NSURLSessionDataTask *getData = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData* data, NSURLResponse *response, NSError* error){
dispatch_async(dispatch_get_main_queue(), ^{
NSString* rawJson = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *value = [rawJson JSONValue];
_featuredProducts = [[NSDictionary alloc]initWithDictionary:value];
NSLog(@"Featured products: %@", _featuredProducts);//not empty
LaunchScreenViewController *lsvc = [[LaunchScreenViewController alloc]init];
lsvc.featuredProducts = self.featuredProducts;
[[[UIApplication sharedApplication] keyWindow] setRootViewController:lsvc];
})
}];
[getData resume];
}