怎么在网站后台挂马,抖音十大传媒公司名称,读取别人网站代码自己做,app手机网站建设深度解析Cocoa异步请求和libxml2.dylib教程是本文要介绍的内容#xff0c;不多说#xff0c;直接进入话题#xff0c;很早就在cocoachina上看到这个框架了,今天终于有机会来使用这个东东了. 我这里写一下,如何往iphone项目中添加这个框架. 步骤如下: 1.下载该framework : ht…深度解析Cocoa异步请求和libxml2.dylib教程是本文要介绍的内容不多说直接进入话题很早就在cocoachina上看到这个框架了,今天终于有机会来使用这个东东了. 我这里写一下,如何往iphone项目中添加这个框架. 步骤如下: 1.下载该framework : http://github.com/pokeb/asi-http-request/tree 2.将class根目录下的文件全拷贝到自己的项目中,另外还要在 External/Reachability/下将其中的Reachability.h/m 也拷贝到自己的项目中. 3.添加需要的framework.可以参考 http://allseeing-i.com/ASIHTTPRequest/Setup-instructions 需要额外添加的有: CFNetwork.framework, MobileCoreServices.framework,SystemConfiguration.framework,libz.1.2.3.dylib,libxml2.dylib 然后运行项目,会发现有很多xml相关的error,不用急,这时因为libxml2.dylib这个framework(这个框架不是很friendly,我们还需要做一些工作). 在xcode中project-edit project settings-然后search search paths,然后在path中添加 /usr/include/libxml2 这样就ok了,可以根据官方的教程来学习了. http://allseeing-i.com/ASIHTTPRequest/How-to-use 我下了一个sample code XMLPerformance 解析xml我建了一个工程照着上面做但是编译时提示错误 error libxml/tree.h: No such file or directory 我立刻想到没有add Frameworks 我把libsqlite3.dylib 和 libxml2.dylib都加进去了但是还是报错。 error libxml/tree.h: No such file or directory An error on the .h is a compile-time error with your Header Search Paths, not a .dylib or a linker error. You have to ensure that /usr/include/libxml2 is in your Header Search Paths in your Release configuration。 在iphone开发中异步操作是一个永恒的话题尤其当iphone手机需要和远程服务器进行交互时使用异步请求是很普遍的做法。 通常这需要NSURLConnection和NSOperation结合起来使用。这方面的资料网络上自然有不少的介绍不过要找一个能运行的代码也并不容易。许多文章介绍的并不全面或者使用了过时的SDK在新IOS版本下并不适用当前最新的ios是4.2了。这些代码很经典但仍然很容易使人误入歧途。 本文总结了众多文档介绍的方法和代码揭示了异步操作中的实现细节和初学者包括笔者易犯的错误使后来者少走弯路。 一、使用NSOperation实现异步请求 1、新建类继承自NSOperation。 interface URLOperation : NSOperation { NSURLRequest* _request; NSURLConnection* _connection; NSMutableData* _data; //构建gb2312的encoding NSStringEncoding enc; } - (id)initWithURLString:(NSString *)url; property (readonly) NSData *data; end 接口部分不多做介绍我们来看实现部分。 首先是带一个NSString参数的构造函数。在其中初始化成员变量。 其中enc是 NSStringEncoding 类型因为服务器返回的字符中使用了中文所以我们通过它指定了一个gb2312的字符编码。 许多资料中说需要在NSOperation中重载一个叫做isConcurrent的函数并在其中返回YES否则不支持异步执行。但是实际上我们在这里注释了这个重载方法程序也没有报任何错误其执行方式依然是异步的。 implementation URLOperation synthesize data_data; - (id)initWithURLString:(NSString *)url { if (self [self init]) { NSLog(%,url); _request [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:url //构建gb2312的encoding enc CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000); _data [[NSMutableData data] retain]; } return self; } - (void)dealloc { [_request release],_requestnil; [_data release],_datanil; [_connection release],_connectionnil; [super dealloc]; } // 如果不重载下面的函数异步方式调用会出错 //- (BOOL)isConcurrent { //如果采用并发就不要使用queueadd5次后会发生运行错误// return YES;//返回yes表示支持异步调用否则为支持同步调用 //} 整个类中最重要的方法是start方法。Start是NSOperation类的主方法主方法的叫法充分说明了其重要性因为这个方法执行完后该NSOperation的执行线程就结束了返回调用者的主线程同时对象实例就会被释放也就意味着你定义的其他代码包括delegate方法也不会被执行。很多资料中的start方法都只有最简单的一句包括“易飞扬的博客 “的博文 [NSURLConnection connectionWithRequest:_request delegate:self]; 如果这样的话delegate方法没有执行机会。因为start方法结束后delegate即self对象已经被释放了delegate的方法也就无从执行。 所以在上面的代码中还有一个while循环这个while循环的退出条件是http连接终止即请求结束。当循环结束我们的工作也就完成了。 // 开始处理-本类的主方法 - (void)start { if (![self isCancelled]) { NSLog(start operation); // 以异步方式处理事件并设置代理 _connection[[NSURLConnection connectionWithRequest:_request delegate:self]retain]; //下面建立一个循环直到连接终止使线程不离开主方法否则connection的delegate方法不会被调用,因为主方法结束对象的生命周期即终止 //这个问题参考 http://www.cocoabuilder.com/archive/cocoa/279826-nsurlrequest-and-nsoperationqueue.html while(_connection ! nil) { [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; } } } 接下来是NSURLConnection的delegate方法这部分的代码和大部分资料的介绍是一样的你可以实现全部的delegate方法但这里我们只实现其中3个就足够了其余的方法不用理会。如你所见你可以在其中添加自己想到的任何代码包括接收数据进行字符编码或者做xml解析。 #pragma mark NSURLConnection delegate Method // 接收到数据增量时 - (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data { NSLog(connection:); NSLog(%,[[NSString alloc] initWithData:data encoding:enc]); // 添加数据 [_data appendData:data]; } // HTTP请求结束时 - (void)connectionDidFinishLoading:(NSURLConnection*)connection { [_connection release],_connectionnil; //NSLog(%,[[NSString alloc] initWithData:_data encoding:enc]); } -(void)connection: (NSURLConnection *) connection didFailWithError: (NSError *) error{ NSLog(connection error); } end 到此虽然代码还没有完成但我们已经可以运行它了。你可以看到console输出的内容观察程序的运行状态。 2、调用NSOperation 我们的NSOperation类可以在ViewController中调用也可以直接放在AppDelegate中进行。 在这里我是通过点击按钮来触发调用代码的 -(void)loginClicked{ //构造登录请求url NSString* url”http://google.com”; _queue [[NSOperationQueue alloc] init]; URLOperation* operation[[URLOperation alloc ]initWithURLString:url]; // 开始处理 [_queue addOperation:operation]; [operation release];//队列已对其retain可以进行release } _queue是一个 NSOperationQueue 对象当往其中添加 NSOperation 对象后 NSOperation 线程会被自动执行不是立即执行根据调度情况。 3、KVO编程模型 我们的NSOperation完成了向服务器的请求并将服务器数据下载到成员变量_data中了。现在的问题是由于这一切是通过异步操作进行的我们无法取得_data中的数据因为我们不知道什么时候异步操作完成以便去访问_data属性假设我们将_data定义为属性了取得服务器数据。 我们需要一种机制当NSOperation完成所有工作之后通知调用线程。 这里我们想到了KVO编程模型键值观察模型。这是cocoa绑定技术中使用的一种设计模式它可以使一个对象在属性值发生变化时主动通知另一个对象并触发相应的方法。 首先我们在NSOperation的子类中添加一个BOOL变量当这个变量变为YES时标志异步操作已经完成 BOOL _isFinished; 在实现中加入这个变量的访问方法 - (BOOL)isFinished { return _isFinished; } cocoa的KVO模型中有两种通知观察者的方式自动通知和手动通知。顾名思义自动通知由cocoa在属性值变化时自动通知观察者而手动通知需要在值变化时调用 willChangeValueForKey:和didChangeValueForKey: 方法通知调用者。为求简便我们一般使用自动通知。 要使用自动通知需要在 automaticallyNotifiesObserversForKey方法中明确告诉cocoa哪些键值要使用自动通知 //重新实现NSObject类中的automaticallyNotifiesObserversForKey:方法返回yes表示自动通知。 (BOOL)automaticallyNotifiesObserversForKey:(NSString*)key { //当这两个值改变时使用自动通知已注册过的观察者观察者需要实现observeValueForKeyPath:ofObject:change:context:方法 if ([key isEqualToString:isFinished]) { return YES; } return [super automaticallyNotifiesObserversForKey:key]; } 然后在需要改变_isFinished变量的地方使用 [self setValue:[NSNumber numberWithBool:YES] forKey:isFinished]; 方法而不是仅仅使用简单赋值。 我们需要在3个地方改变isFinished值为YES请求结束时、连接出错误线程被cancel。请在对应的方法代码中加入上面的语句。 最后需要在观察者的代码中进行注册。打开ViewController中调用NSOperation子类的地方加入 //kvo注册 [operation addObserver:self forKeyPath:isFinished options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:operation]; 并实现 observeValueForKeyPath 方法 //接收变更通知 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqual:isFinished]) { BOOL isFinished[[change objectForKey:NSKeyValueChangeNewKey] intValue]; if (isFinished) {//如果服务器数据接收完毕 [indicatorView stopAnimating]; URLOperation* ctx(URLOperation*)context; NSStringEncoding encCFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000); NSLog(%,[[NSString alloc] initWithData:[ctx data] encoding:enc]); //取消kvo注册 [ctx removeObserver:self forKeyPath:isFinished]; } }else{ // be sure to call the super implementation // if the superclass implements it [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } 运行程序查看控制台的输出。 转载于:https://www.cnblogs.com/pengyingh/articles/2355273.html