1

我是 Objective-C 的新手,我想知道我的方法是否有意义。

我的应用程序是基于选项卡视图的。每个选项卡都会调用对服务器的请求。

  1. 在我appDelegate的服务器中,我创建了一个异步套接字连接实例。
  2. 我单击“获取状态”选项卡,该选项卡加载了TableViewController我需要在其中创建内部请求消息并将其发送到服务器。
  3. 我的问题是我无法访问 中的套接字TableViewController,所以我可以通过appDelegate sharedApplication然后将请求消息发送到服务器来访问套接字。

  4. 由于我使用异步套接字模型,接收服务器响应的委托就是它appDelegate本身,现在我需要以某种方式将响应传播回 "Get status" TableViewController

我的问题是如何做到这一点?

也许我的方法不好开始,我需要使用同步套接字模型。或者我可能需要将套接字连接作为上下文传递给我打开的每个视图控制器。

我错过了什么??我怎样才能从我发送它的视图中轻松访问对服务器的响应?任何帮助,将不胜感激!!

谢谢!

4

3 回答 3

1

我建议一个不同的设计。发出请求的东西应该是任何 VC 都可以实例化并用来发出请求的类,可能是 NSURLRequest 的子类。

因为它是一个单例,所以很容易让应用程序委托一个全局数据和行为的持有者,但这不是它的工作。

如果你对服务器请求有很多自定义工作要做,请子类化 NSURLRequest。使用 NSURLConnection 的 sendAsynchronousRequest: 方法运行它。它允许调用者在完成时传递一个块以执行请求结果。

例如 MyRequest.h

@interface MyRequest : NSMutableURLRequest
- (id)initWithParams:(NSDictionary *)params;
- (void)runWithCompletion:(void (^)(id result, NSError *error))completion;
@end

例如 MyRequest.m

@implementation MyRequest

- (id)initWithParams:(NSDictionary *)params {

    self = [self init];
    if (self) {
        // do custom init here, e.g.
        self.URL = @"http://www.myservice.com/myrequest.json"
        [self setValue:@"bar" forHTTPHeaderField:@"foo"];      // more realistically, using key value pairs in the params dictionary
        // and so on
    }
    return self;
}

- (void)runWithCompletion:(void (^)(id result, NSError *error))completion {

    [NSURLConnection sendAsynchronousRequest:self
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                               if (data) {
                                   // do something custom with the received data here,
                                   // like convert to a string and parse as json, etc.
                                   completion(data, nil);
                               } else {
                                   completion(nil, error);
                               }
                           }];
}

@end

现在,任何 VC——或任何其他类——都可以创建其中一个并使用它:

// in MyVC.m

MyRequest *myRequest = [[MyRequest alloc] initWithParams:[NSDictionary dictionary]];
[myRequest runWithCompletion:^(id result, NSError *error) {
    // do main thread ui stuff with the result in hand, e.g.
    [self.tableView reloadData];
}];
于 2012-12-31T15:59:44.843 回答
0

我同意 Talha 对此的评论,不建议使用通知中心。最好创建一个从 NSObject 继承的新类来处理套接字事件,但如果需要,您也可以仅使用应用程序委托使其工作。为了方便您...

创建从套接字类到视图控制器的链接

在两个文件都可以看到的地方定义 TableViewSocketEventsDelegate。您可以创建一个公共的 Constants.h 或其他东西。

@protocol TableViewSocketEventsDelegate <NSObject>

@required
- (void) someSocketEvent:(int)statusCode;
//TODO: Add callbacks that make sense here
@end

为套接字类(在您的情况下为应用程序委托 .h 文件)提供对最终处理操作的内容(在您的情况下为表视图控制器)的引用

@property (nonatomic, assign) id<TableViewSocketEventsDelegate> socketDelegate;

并且在 .m 中一定要合成 socketDelegate 并将其分配给适当的视图控制器。

接下来告诉视图控制器它可以处理这些委托回调。

在.h中:

ViewController : UITableViewController<TableViewSocketEventsDelegate>

以 .m 为单位:

#pragma mark - TableViewSocketEventsDelegate

- (void) someSocketEvent:(int)statusCode
{
    NSLog(@"Some socket event happened %I", statusCode);
}

现在您所要做的就是更改应用程序委托中处理套接字的现有方法以调用新方法

if (self.socketDelegate) {
        [self.socketDelegate someSocketEvent:2];
    }

这对你有意义吗?如果它们都需要处理同一个委托,我还建议为所有选项卡视图控制器创建一个基类。

祝你好运!

于 2012-12-31T15:53:52.930 回答
0

您可以让您的代理人在通知中心发布通知。然后您的表视图控制器注册到该通知,它可以接收信息。

就像是

在您的 AppDelegate中,当接收到套接字响应时

NSDictionary * userInfo = @{@"socketResponse" : response}; // assuming that response is the object to pass around
[[NSNotificationCenter defaultCenter] postNotificationName:@"kDidReceiveSocketResponse"
                                                    object:self
                                                  userInfo:userInfo

在你的 UITableViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //...
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(socketResponseReceived:) 
                                                 name:@"kDidReceiveSocketResponse"
                                               object:nil];
    //...
}

- (void)socketResponseReceived:(NSDictionary *)userInfo {
     id response = userInfo[@"socketResponse"];
     // do whatever you like
}

- (void)dealloc {
     [[NSNotificationCenter defaultCenter] removeObserver:self];
}
于 2012-12-31T14:35:44.123 回答