解析文件和多线程 线程同步
来源:互联网 发布:中国十大网络神兽动图 编辑:程序博客网 时间:2024/06/05 14:56
系统自带的解析
NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:receiveData options:NSJSONReadingAllowFragments error:nil];
JSON解析 get连接 (JSON解析除了有JSONKit外还有SBJSON(即 json-framework) TouchJSON JSON的数据可读性不如XML)
josn里文件的对应关系:
Number -> NSNumber String -> NSString Array -> NSArray Object -> NSDictionary 另外:null -> NNSNull true and false -> NNSNumber
NSStringEncoding encode = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);//可以转码的工具这个是非UTF8的
NSString *urlString = [[NSString alloc] initWithFormat:@"http://api.tudou.com/v3/gw?method=item.ranking&appKey=myKey&format=json&pageNo=1&pageSize=20&channelId=22&inDays=30&sort=m"];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL: [NSURL URLWithString:urlString]];
NSString *jsonString = [[NSString alloc] initWithData:receiveData encoding:NSUTF8StringEncoding];
[jsonString objectFromJSONString]; 或者 NSDictionary *data = [json objectFromJSONStringWithParseOptions:JKParseOptionLooseUnicode];
[jsonDicOutside valueForKey:@"multiPageResult"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://tm.mbpay.cn:8082"]];
request.HTTPMethod = @"POST";
request.HTTPBody = requestData;(NSData *requestData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"request" ofType:@"xml"]];post携带的数据一般由服务器人提供)
[NSURLConnection connectionWithRequest:request delegate:self];
GDataXMLDocument *xmlDocument = [[GDataXMLDocument alloc] initWithData:self.receiveData options:0 error:NULL];
NSArray *nodes = [xmlDocument nodesForXPath:@"//body//rows//wp_film" error:NULL];//可以打印一下xmlDocument看内容再取节点
for (GDataXMLDocument *node in nodes) //遍历数组方便下面引用
myMovie.movieID = [[node attributeForName:@"id"] stringValue];//具体用数据了
线程同步:多线程同时操作一个数据 对数据添加保护 这个保护就是线程同步
线程异步:多个线程互不影响分别操作自己的数据
并发:多个线程同时运行
线程间通信:一个线程执行之后另一个线程开始执行
线程开销:线程切换之间的资源耗费(时间和空间)
线程互斥:多个线程访问同一个数据的时候的 只允许一个线程修改 执行互斥操纵以前先检查NSLock 打开状态则可继续运行并设置为关闭状态
线程下载完图片后怎么通知主线程更新界面呢?
[self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
NSThread:
代表执行的线程,可以使用该类的对象封装线程操作。
[NSTread detachNewThreadSelector:@selector(task) toTarget:self withObject:nil];//系统
[NSThread *_thread =[[NSThread alloc] initWithTarget:self selector:@selector(task) object:nil];//类自己开辟线程 自己管理
[_thread start];
NSOperation
定义了任务的执行环境、状态等基本属性,继续该类来指定具体的操作,通常情况下,编写NSOperation的子类来定义具体的操作。该类为抽象类,NSOperation的子类(NSInvocationOperation(可能要用到NSInvocation签名)和NSBlockOperation) 可以指定操作方法。
NSInvocationOperation *op=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task) object:nil];
[op start];
NSOperationQueue:
运行队列(Operation queue)的管理者,配合NSOperation的子类对象和NSIvocationOperation对象使用,通过添加操作对象完成并发操作。将Operation对象放入NSOperationQueue里,系统会自动生成一个线程来执行Operation 如果将最大的并发数设置为1的话则同时只有一个线程运行,由此解决线程同步问题
NSOperationQueue *queue=[[NSOperation alloc] init]
[queue setMaxConcurrentOperationCount:1];//指定能够同时并发执行的操作个数
[queue addOperation:op];
NSRunLoop:
表示程序的运行回路,该类的对象可以接收到各种时间(如来自NSTimer的时间变化),协助程序对这些事件做出响应。
GCD
NSOperationQueue *queue = [[NSOperation alloc]init];
[queue setMaxConcurrentOperationCount:1];
方法1: 同步加载图片(很慢)
[self loadImageForMovie:movie];
方法1.1: 用NSInvocation同步加载图片
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(loadAndRefreshForMovie:)]];
//根据方法签名创建一个NSInvocation invocation.target = self; invocation.selector = @selector(loadAndRefreshForMovie:);
[invocation setArgument:&movie atIndex:2];//retain 所有参数,防止参数被释放dealloc argument 为参数的指针
index 为参数的位置(注意:由2开始)原因为:0 1 两个参数已经被target 和selector占用
//消息调用
[invocation invoke];
方法2: 用NSThread(手动开始)
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(loadAndRefreshForMovie:) object:movie];
[thread start];
[thread release];
方法3: NSThread简便写法
[NSThread detachNewThreadSelector:@selector(loadAndRefreshForMovie:) toTarget:self withObject:movie];
方法4: 使用NSInvocationOperation和NSOperationQueue来做多线程加载图片
// 创建invocation对象
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(loadAndRefreshForMovie:)]];
invocation.target = self;
invocation.selector = @selector(loadAndRefreshForMovie:);
[invocation setArgument:&movie atIndex:2];
// 把invocation对象封装为NSInvocationOperation
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithInvocation:invocation];
// 把operation对象加到operation queue里
[self.operationQueue addOperation:operation];
[operation release];
方法5: 用GCD-GrandCentralDispath来执行后台加载和刷新
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self loadImageForMovie:movie];dispatch_async(dispatch_get_main_queue(), ^{
[self refreshTableViewCellForMovie:movie];});
});
方法6不显式创建线程的方法:用NSObject的类方法 performSelectorInBackground:withObject: 创建一个线程当多个线程同时运行时,就会出现访问资源的同步问题.
[self performSelectorInBackground:@selector(loadAndRefreshForMovie:) withObject:movie];
方法7: addOperationWithBlock 添加一个块到线程队列
[self.operationQueue addOperationWithBlock:^{
[self loadAndRefreshForMovie:movie];
}];
线程同步
我们演示一个经典的卖票的例子来讲NSThread的线程同步:
- #import <UIKit/UIKit.h>
- @class ViewController;
- @interface AppDelegate : UIResponder <UIApplicationDelegate>
- {
- int tickets;
- int count;
- NSThread* ticketsThreadone;
- NSThread* ticketsThreadtwo;
- NSCondition* ticketsCondition;
- NSLock *theLock;
- }
- @property (strong, nonatomic) UIWindow *window;
- @property (strong, nonatomic) ViewController *viewController;
- @end
如果没有线程同步的lock,卖票数可能是-1.加上lock之后线程同步保证了数据的正确性。
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
- {
- tickets = 100;
- count = 0;
- theLock = [[NSLock alloc] init];
- // 锁对象
- ticketsCondition = [[NSCondition alloc] init];
- ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
- [ticketsThreadone setName:@"Thread-1"];
- [ticketsThreadone start];
- ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
- [ticketsThreadtwo setName:@"Thread-2"];
- [ticketsThreadtwo start];
- self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
- // Override point for customization after application launch.
- self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
- self.window.rootViewController = self.viewController;
- [self.window makeKeyAndVisible];
- return YES;
- }
- - (void)run{
- while (TRUE) {
- // 上锁
- // [ticketsCondition lock];
- [theLock lock];
- if(tickets >= 0){
- [NSThread sleepForTimeInterval:0.09];
- count = 100 - tickets;
- NSLog(@"当前票数是:%d,售出:%d,线程名:%@",tickets,count,[[NSThread currentThread] name]);
- tickets--;
- }else{
- break;
- }
- [theLock unlock];
- // [ticketsCondition unlock];
- }
- }
上面例子我使用了两种锁,一种NSCondition ,一种是:NSLock。 NSCondition我已经注释了。线程的顺序执行
他们都可以通过
[ticketsCondition signal]; 发送信号的方式,在一个线程唤醒另外一个线程的等待。
比如:
wait是等待,我加了一个 线程3 去唤醒其他两个线程锁中的wait
- #import "AppDelegate.h"
- #import "ViewController.h"
- @implementation AppDelegate
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
- {
- tickets = 100;
- count = 0;
- theLock = [[NSLock alloc] init];
- // 锁对象
- ticketsCondition = [[NSCondition alloc] init];
- ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
- [ticketsThreadone setName:@"Thread-1"];
- [ticketsThreadone start];
- ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
- [ticketsThreadtwo setName:@"Thread-2"];
- [ticketsThreadtwo start];
- NSThread *ticketsThreadthree = [[NSThread alloc] initWithTarget:self selector:@selector(run3) object:nil];
- [ticketsThreadthree setName:@"Thread-3"];
- [ticketsThreadthree start];
- self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
- // Override point for customization after application launch.
- self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
- self.window.rootViewController = self.viewController;
- [self.window makeKeyAndVisible];
- return YES;
- }
- -(void)run3{
- while (YES) {
- [ticketsCondition lock];
- [NSThread sleepForTimeInterval:3];
- [ticketsCondition signal];
- [ticketsCondition unlock];
- }
- }
- - (void)run{
- while (TRUE) {
- // 上锁
- [ticketsCondition lock];
- [ticketsCondition wait];
- [theLock lock];
- if(tickets >= 0){
- [NSThread sleepForTimeInterval:0.09];
- count = 100 - tickets;
- NSLog(@"当前票数是:%d,售出:%d,线程名:%@",tickets,count,[[NSThread currentThread] name]);
- tickets--;
- }else{
- break;
- }
- [theLock unlock];
- [ticketsCondition unlock];
- }
- }
其他同步
我们可以使用指令 @synchronized 来简化 NSLock的使用,这样我们就不必显示编写创建NSLock,加锁并解锁相关代码。
- (void)doSomeThing:(id)anObj
{
@synchronized(anObj)
{
// Everything between the braces is protected by the @synchronized directive.
}
}
还有其他的一些锁对象,比如:循环锁NSRecursiveLock,条件锁NSConditionLock,分布式锁NSDistributedLock等等,可以自己看官方文档学习
NSCondition的用法
使用NSCondition,实现多线程的同步,即,可实现生产者消费者问题。
基本思路是,首先要创建公用的NSCondition实例。然后:
- 消费者取得锁,取产品,如果没有,则wait,这时会释放锁,直到有线程唤醒它去消费产品;
- 生产者制造产品,首先也是要取得锁,然后生产,再发signal,这样可唤醒wait的消费者。
- (IBAction)conditionTest:(id)sender{ NSLog(@"begin condition works!"); products = [[NSMutableArray alloc] init]; condition = [[NSCondition alloc] init]; [NSThread detachNewThreadSelector:@selector(createProducter) toTarget:self withObject:nil]; [NSThread detachNewThreadSelector:@selector(createConsumenr) toTarget:self withObject:nil];}- (void)createConsumenr{ [condition lock]; while ([products count] == 0) { NSLog(@"wait for products"); [condition wait]; } [products removeObjectAtIndex:0]; NSLog(@"comsume a product"); [condition unlock];}- (void)createProducter{ [condition lock]; [products addObject:[[NSObject alloc] init]]; NSLog(@"produce a product"); [condition signal]; [condition unlock];}
- 解析文件和多线程 线程同步
- 文件IO,多线程,线程同步
- [Win32] 多线程和线程同步
- 多线程、委托、线程同步举例及解析!
- java-多线程 | 线程安全和线程同步
- JAVA多线程实现和线程同步总结
- 【Java多线程】-线程同步synchronized和volatile
- [网络和多线程]4、线程同步
- PV 线程同步和多线程问题
- Java多线程之线程同步和死锁
- 基础-线程-同步、异步和多线程
- JavaSE:Java多线程并发和线程同步
- Java 多线程和线程同步总结
- VC++多线程编程-线程间的通信和线程同步
- POSIX线程之二. 线程同步,属性和多线程
- Thread(线程)详解2—多线程同步和线程池
- java多线程(二)之线程安全和线程同步
- 多线程-线程同步
- android 内存优化详解
- 世界上最受欢迎的10个Linux发行版
- android开发中常用的快捷键
- 2014年华为校招机试题目
- IO流对文件的续写
- 解析文件和多线程 线程同步
- ASIHTTPRequest-使用download cache
- 各种心境
- Android常用权限permission
- ASP.NET基础知识
- POJ1328 Radar Installation
- java学习脚印:集合(Collection)之实现类
- @ property @ synthesize
- 作为一个JAVA程序员,我经常去的地方