如何在 NSOperation 中启动异步 NSURLConnection?

2023-12-01

我想在后台线程上的 NSOperation 内部执行异步 NSURLConnection 。 这是因为当数据返回时我正在对数据进行一些非常昂贵的操作。

这与他们在这里提出的问题非常相似:如何在 NSOperation 中执行异步 NSURLConnection?

但不同之处在于我在另一个类中运行连接。

这是我的第一次尝试:

在我的 MainViewController 中:

@property (nonatomic, strong) NSOperationQueue *requestQueue;

#pragma mark - Lazy initialization
- (NSOperationQueue *)requestQueue 
{
    if (!_requestQueue) {
        _requestQueue = [[NSOperationQueue alloc] init];
        _requestQueue.name = @"Request Start Application Queue";
        _requestQueue.maxConcurrentOperationCount = 1;
    }
    return _requestQueue;
}

-(void)callToServer
{
URLJsonRequest *request = [URLRequestFactory createRequest:REQUEST_INTERFACE_CLIENT_VERSION
                                                         delegate:self];

    RequestSender *requestSender = [[RequestSender alloc]initWithPhotoRecord:request delegate:self];

   [self.requestQueue addOperation:requestSender];
}

这是我的操作:

- (id)initWithPhotoRecord:(URLJsonRequest *)request
                 delegate:(id<RequestSenderDelegate>) theDelegate{

    if (self = [super init])
    {
        self.delegate = theDelegate;
        self.jsonRequest = request;
    }
    return self;
}

- (void)main {

    //Apple recommends using @autoreleasepool block instead of alloc and init NSAutoreleasePool, because blocks are more efficient. You might use NSAuoreleasePool instead and that would be fine.
    @autoreleasepool
    {

        if (self.isCancelled)
            return;

        [self.jsonRequest start];

    }
}

这是我的请求启动功能:

-(void) start
{
  NSURL *url = [NSURL URLWithString:@"http://google.com"];
 NSURLRequest *theRequest = [NSURLRequest requestWithURL:url];
  urlConnection = [[[NSURLConnection alloc]    initWithRequest:theRequest delegate:self]autorelease];

[urlConnection start];
[theRequest release]
}


- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
    NSLog(@"Received reponse from connection");
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{



}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection{

}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{

}

我没有收到服务器的响应。


几种方法:

  1. 安排NSURLConnection在主运行循环中,通过使用startImmediately的参数NO,设置运行循环,然后才可以启动连接,例如:

    urlConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:NO];
    [urlConnection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
    [urlConnection start];
    
  2. 为该连接创建一个专用线程,并在为该线程创建的运行循环中安排该连接。看AFURLConnectionOperation.m in AF网络一个例子的来源。

  3. 实际使用AF网络,这给了你NSOperation您可以将其添加到队列中,并为您处理运行循环的操作。


因此,AFNetworking 会执行以下操作:

+ (void)networkRequestThreadEntryPoint:(id)__unused object {
    @autoreleasepool {
        [[NSThread currentThread] setName:@"NetworkingThread"];

        NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
        [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
        [runLoop run];
    }
}

+ (NSThread *)networkRequestThread {
    static NSThread *_networkRequestThread = nil;
    static dispatch_once_t oncePredicate;

    dispatch_once(&oncePredicate, ^{
        _networkRequestThread = [[NSThread alloc] initWithTarget:self
                                                        selector:@selector(networkRequestThreadEntryPoint:)
                                                          object:nil];
        [_networkRequestThread start];
    });

    return _networkRequestThread;
}

所以我做了如下的事情。首先我有一些私有属性:

@property (nonatomic, readwrite, getter = isExecuting)  BOOL executing;
@property (nonatomic, readwrite, getter = isFinished)   BOOL finished;
@property (nonatomic, weak)   NSURLConnection *connection;

然后网络操作可以执行如下操作:

@synthesize executing = _executing;
@synthesize finished  = _finished;

- (instancetype)init {
    self = [super init];
    if (self) {
        _executing = NO;
        _finished = NO;
    }
    return self;
}

- (void)start {
    if (self.isCancelled) {
        [self completeOperation];
        return;
    }

    self.executing = YES;

    [self performSelector:@selector(startInNetworkRequestThread)
                 onThread:[[self class] networkRequestThread]
               withObject:nil
            waitUntilDone:NO];
}

- (void)startInNetworkRequestThread {
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:self.request
                                                                  delegate:self
                                                          startImmediately:NO];
    [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
    [connection start];

    self.connection = connection;
}

- (void)completeOperation {
    self.executing = NO;
    self.finished = YES;
}

- (void)setFinished:(BOOL)finished {
    if (finished != _finished) {
        [self willChangeValueForKey:@"isFinished"];
        _finished = finished;
        [self didChangeValueForKey:@"isFinished"];
    }
}

- (void)setExecuting:(BOOL)executing {
    if (executing != _executing) {
        [self willChangeValueForKey:@"isExecuting"];
        _executing = executing;
        [self didChangeValueForKey:@"isExecuting"];
    }
}

- (BOOL)isConcurrent {
    return YES;
}

- (BOOL)isAsynchronous {
    return YES;
}

// all of my NSURLConnectionDataDelegate stuff here, for example, upon completion:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    // I call the appropriate completion blocks here, do cleanup, etc. and then, when done:

    [self completeOperation];
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 NSOperation 中启动异步 NSURLConnection? 的相关文章

  • 如何向标准 UIButton 添加徽章? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 是否可以在标准中添加看起来标准的徽章UIButton 如果不支持半原生 那么实现此目的最简单的方法是什么 示例图片 这是 Sascha
  • 访问目标 c 中的类方法。使用 self 还是类名?

    我正在学习 iOS 编程 并且对以下有关关键字 self 的使用的代码感到困惑 据我了解 self就像Java的this 它指的是当前实例 当我想调用类方法时 通常的方式应该是这样 PlayingCard validSuits 但是侵入实例
  • UITableViewCell显示多种字体

    我想在 uitableviewcell 中以类似于 iPhone 地址簿的不同字体显示两个单词 例如 约翰Buchanan 您应该使用两个 UILable 或者您可以使用OH属性标签 https github com AliSoftware
  • iPhone:UIApplication WillResignActiveNotification 从未被调用

    我正在视图控制器中播放视频 当用户按下硬件主页按钮并且当前正在播放视频时 应用程序崩溃并显示EXC BAD ACCESS在模拟器中 我读到我应该使用applicationWillResignActive停止视频播放的消息应该可以解决崩溃问题
  • 编码时捕获 NS_AVAILABLE_IOS

    我知道如何更改支持的最低操作系统IPHONEOS DEPLOYMENT TARGET 我目前正在 Xcode 4 5 下进行开发并使用 iOS 6 0 SDK 我想做的是找到一种方法 每当我使用标记的代码时在编译中抛出警告 NS AVAIL
  • 如何在 UICollectionView 中将行居中?

    我有一个UICollectionView与随机细胞 有什么方法可以让我将行居中吗 默认情况下它是这样的 x x x x x x x x x x x x x x 这是所需的布局 x x x x x x x x x x x x 我必须做这样的事
  • 为什么 Objective-C 允许在方法定义末尾使用分号? [复制]

    这个问题在这里已经有答案了 可能的重复 Objective C 实现文件中方法名后面的分号 https stackoverflow com questions 5678360 semicolon after the method name
  • 隐藏选项卡栏项目并对齐其他选项卡项目

    在我的应用程序中 我有 4 个选项卡栏项目 我正在 XIB 文件中添加这 4 个选项卡栏项目 最初我必须显示 3 个选项卡栏项目 同步后我必须在我的应用程序中显示第 4 个选项卡栏项目 因此 为此 我使用以下代码隐藏第四个选项卡栏项目 se
  • iOS 应用程序测试。应用程序安装失败。找不到代码签名[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我尝试在多个 iOS 设备上安装我的应用程序 但这件事不让我这么做 我想知道 问题是什么以及我应该如何解决它 就我而言
  • ios如何搜索目录

    我想知道如何检查我的应用程序中是否存在目录 例如 如果我想搜索我的应用程序文档中是否存在文件夹 以及如何在其中创建新文件夹 此致 检查文件是否存在 BOOL fileExistsAtAbsolutePath NSString filenam
  • 如何使用 (a)smack 在 Android 上保持 XMPP 连接稳定?

    我使用适用于 Android 的 asmack android 7 beem 库 我有一个后台服务正在运行 例如我的应用程序保持活动状态 但 XMPP 连接迟早会在没有任何通知的情况下消失 服务器表示客户端仍然在线 但没有发送或接收数据包
  • HttpClient setReachabilityStatusChangedBlock 声明没有接口

    尝试使用 AFNetworkings ReachabilityStatusChanged 但得到 HTTPCLIENT 没有可见的 interface 声明选择器 setReachabilityStatusChangeBlock 但Http
  • 强制本地化图像或图像资产

    正如在这个问题中 如何强制 NSLocalizedString 使用特定语言 https stackoverflow com questions 1669645 how to force nslocalizedstring to use a
  • 如何使用 MonoTouch c# 以编程方式获取联系人?

    如何获取 iPhone 中的联系人 我需要从 iPhone 联系人中获取所有属性 如何使用MonoTouch以编程方式实现 ABAddressBook iPhoneAddressBook new ABAddressBook ABPerson
  • 使用 HTTP NSURL 创建 AVAsset

    我正在尝试合并两个NSURLs包含视频参考 其中一个 URL 指向 AWS 上的视频 另一个 URL 指向本地存储的视频 我的导出代码有效 因为我已经尝试使用两个本地视频 但每当我尝试合并 HTTP url 和本地 url 时 我都会收到此
  • 尽早检测有问题的 XIB 视图

    我的笔尖名称有一个拼写错误 当我推向导航控制器时 它在代码中被破坏了 弄清楚它并没有花太长时间 但我认为最好尽早断言格式良好 以便更容易弄清楚 问题是它不是零 它只是无法从笔尖正确地形成自己 在 initWithNib 之后是否有更好的断言
  • 块如何捕获其封闭范围之外的变量?

    我知道 Objective C 块可以捕获并设置其封闭范围之外的变量值 它是如何做到的 它实际上相当简单 并在 Clang 的块实现规范中进行了描述 在 导入变量 http clang llvm org docs Block ABI App
  • Objective-C 中 NSURL 为 null 而 NSString 是正确的

    我有一个NSString包含一个 url 以及当我分配时NSURL与NSString NSURL 输出 空 这是因为url中有一些非法字符 导致NSURL不编码就无法读取NSString包含网址 NSString u incomingUrl
  • 出现错误:FT_Open_Face 失败:错误 2

    当我使用时出现以下错误CGContextDrawPDFPage context PDFPage 对于某些文件 有解决办法来解决这个问题吗 FT Open Face failed error 2 错误2看起来像errno2 这是 找不到文件
  • 初始化Object中的空字符串?

    有人使用以下方法来初始化 NSstring NSString astring NSString alloc init 我想知道为什么不直接使用 NSString atring nil or NSString astring 没有semant

随机推荐