js333 > 计算机互联网 > 多线程编程,开发上传管理器金沙js333娱乐场:

原标题:多线程编程,开发上传管理器金沙js333娱乐场:

浏览次数:131 时间:2019-11-29

IOS 开发上传管理器

由于项目需要整合多处的上传功能,涉及到的主要有数据库(FMDB),多线程()

关于多线程编程首先我们要了解清楚什么是线程,什么是进程,以及他们之间的区别和联系。

所谓的线程就是CPU调度(执行任务)的最小单位,其实就是一段代码。

而进程是CPU分配资源和调度的单位,说明白点就是系统中正在运行的一个应用程序。

1.block底层原理
闭包(block),闭包就是能够读取其它函数内部变量的函数
Objective-C是对C语言的扩展,block的实现是基于指针和函数指针。
一个 block 实际是一个对象,它主要由一个 isa 和 一个 impl 和 一个 descriptor 组成。
2.百度地图基本API

1、新建项目,下载依赖库

首先新建一个项目这里命名为UploadManager,项目依赖库采用CocoaPods来管理所以在终端进入UploadManager项目中,输入

 

pod init

这时会看到项目中多了一个文件Podfile,然后打开它,其内容如下:

 

 

# Uncomment this line to define a global platform for your project
# platform :ios, '6.0'

target 'UploadManager' do

end

target 'UploadManagerTests' do

end

然后添加FMDB信息,如下:

 

 

# Uncomment this line to define a global platform for your project
# platform :ios, '6.0'

target 'UploadManager' do
pod'FMDB','2.5'
end

target 'UploadManagerTests' do

end

然后关闭项目,回到终端,输入

 

 

pod install

会自动分析依赖库,并下载下来,等待一段时间后,终端出现如下内容,就说明下载完毕

 

 

Analyzing dependencies

CocoaPods 0.37.1 is available.
To update use: `gem install cocoapods`

For more information see http://blog.cocoapods.org
and the CHANGELOG for this version http://git.io/BaH8pQ.

Downloading dependencies
Installing FMDB (2.5)
Generating Pods project
Integrating client project

[!] Please close any current Xcode sessions and use `UploadManager.xcworkspace` for this project from now on.

然后打开项目目录,会看到项目中多了一些内容,打开其中的UploadManager.xcworkspace

两者的联系和区别

线程是进程的组成部分,一个进程可以开启多个子线程,但是每一个进程至少需要有一个线程;

一个进程的所有任务都是在线程中执行的

同一个进程内的线程共享进程的资源

import <BaiduMapAPI_Map/BMKMapView.h>// 地图视图

2、多线程处理

项目中采用NSOperationQueue和NSOperation来实现多线程操作和管理,设计PendingOperations类来保存上传任务队列、完成任务队列以及线程队列,MerchantTask类自定义NSOperation来实际完成任务,其中添加一个协议MerchantTaskDelegate来实现更新UI界面的进度,代码如下:

 

 

//
//  PendingOperations.h
//  UploadManager
//
//  Created by Soheil M. Azarpour on 8/11/12.
//  Copyright (c) 2012 iOS Developer. All rights reserved.
//

#import 

@interface PendingOperations : NSObject

@property (nonatomic, strong) NSMutableDictionary *uploadInProgress;
@property (nonatomic, strong) NSMutableDictionary *uploadFinishProgress;
@property (nonatomic, strong) NSOperationQueue *uploadQueue;


@end



//
//  PendingOperations.m
//  UploadManager
//
//  Created by Soheil M. Azarpour on 8/11/12.
//  Copyright (c) 2012 iOS Developer. All rights reserved.
//

#import "PendingOperations.h"

@implementation PendingOperations
@synthesize uploadInProgress = _uploadInProgress;
@synthesize uploadFinishProgress = _uploadFinishProgress;
@synthesize uploadQueue = _uploadQueue;



- (NSMutableDictionary *)uploadInProgress {
    if (!_uploadInProgress) {
        _uploadInProgress = [[NSMutableDictionary alloc] init];
    }
    return _uploadInProgress;
}

- (NSOperationQueue *)uploadQueue {
    if (!_uploadQueue) {
        _uploadQueue = [[NSOperationQueue alloc] init];
        _uploadQueue.name = @"Upload Queue";
        _uploadQueue.maxConcurrentOperationCount = 4;
    }
    return _uploadQueue;
}

@end



//
//  MerchantTask.h
//  UploadManager
//
//  Created by 张杰 on 15/5/8.
//  Copyright (c) 2015年 张杰. All rights reserved.
//

#import 
#import "UploadTable.h"

@protocol MerchantTaskDelegate;

@interface MerchantTask : NSOperation

@property (nonatomic, assign) id  delegate;
@property (nonatomic, readonly, strong) NSIndexPath *indexPathInTableView;
@property (nonatomic, readonly, strong) UploadTable *taskRecord;

- (id)initWithTaskRecord:(UploadTable *)record atIndexPath:(NSIndexPath *)indexPath delegate:(id) theDelegate;

-(NSString *) uploadText : (NSString*)textUrl withText:(NSString*)text;

-(NSString *) uploadPic : (NSString *)picUrl widthPicText:(NSString*)picText;

-(NSString *) sysPicInfo : (NSString *)sysUrl withSysText:(NSString*) sysText;

@end

@protocol MerchantTaskDelegate 

// 5: In your delegate method, pass the whole class as an object back to the caller so that the caller can access both indexPathInTableView and photoRecord. Because you need to cast the operation to NSObject and return it on the main thread, the delegate method canít have more than one argument.
- (void) merchantTaskDidFinish:(MerchantTask *)uploader;

@end

在ViewController中实现MerchantTaskDelegate这个协议,来实现在线程中更新UI

//
//  MerchantTask.m
//  UploadManager
//  Created by 张杰 on 15/5/8.
//  Copyright (c) 2015年 张杰. All rights reserved.
//

#import "MerchantTask.h"

@interface MerchantTask()
@property (nonatomic, readwrite, strong) NSIndexPath *indexPathInTableView;
@property (nonatomic, readwrite, strong) UploadTable *taskRecord;
@end


@implementation MerchantTask
@synthesize delegate = _delegate;
@synthesize indexPathInTableView = _indexPathInTableView;
@synthesize taskRecord = _taskRecord;

#pragma mark - Life Cycle
- (id)initWithTaskRecord:(UploadTable *)record atIndexPath:(NSIndexPath *)indexPath delegate:(id) theDelegate
{
    if (self = [super init]) {
        // 2: Set the properties.
        self.delegate = theDelegate;
        self.indexPathInTableView = indexPath;
        _taskRecord = record;
    }
    return self;
}

-(void) main{
    @autoreleasepool {
        _taskRecord.starting = TRUE;
        [self uploadText:@"http://www.ssd" withText:@"dadfasdfad"];
    }

}
//未处理:0;文字上传中:1;文字上传失败:2;图片未上传:3;图片上传中:4;图片上传失败:5;图片同步中:6;图片同步失败:7
-(NSString *)uploadText:(NSString *)textUrl withText:(NSString *)text{
    _taskRecord.upload_progress = 1;
    _taskRecord.upload_status = 0;
    [(NSObject *)self.delegate performSelectorOnMainThread:@selector(merchantTaskDidFinish:) withObject:self waitUntilDone:NO];
    NSLog(@"开始上传文字");
    usleep(1000*1000);
    [self uploadPic:@"http://www.pic" widthPicText:@"上传图片"];

    return @"";
}

-(NSString *)uploadPic:(NSString *)picUrl widthPicText:(NSString *)picText{
    _taskRecord.upload_progress = 3;
    _taskRecord.upload_status = 1;
    [(NSObject *)self.delegate performSelectorOnMainThread:@selector(merchantTaskDidFinish:) withObject:self waitUntilDone:NO];
    NSLog(@"开始上传图片");
    usleep(1000*1000);
    _taskRecord.upload_progress = -1;
    _taskRecord.upload_status = 1;
    _taskRecord.upload_show_text = [NSString stringWithFormat:@"%d %@", 10, @"%"];
    [(NSObject *)self.delegate performSelectorOnMainThread:@selector(merchantTaskDidFinish:) withObject:self waitUntilDone:NO];
    usleep(1000*2000);
    _taskRecord.upload_progress = -1;
    _taskRecord.upload_status = 1;
    _taskRecord.upload_show_text = [NSString stringWithFormat:@"%d %@", 30, @"%"];
    [(NSObject *)self.delegate performSelectorOnMainThread:@selector(merchantTaskDidFinish:) withObject:self waitUntilDone:NO];
    usleep(1000*3000);
    _taskRecord.upload_progress = -1;
    _taskRecord.upload_status = 1;
    _taskRecord.upload_show_text = [NSString stringWithFormat:@"%d %@", 70, @"%"];
    [(NSObject *)self.delegate performSelectorOnMainThread:@selector(merchantTaskDidFinish:) withObject:self waitUntilDone:NO];
    usleep(1000*4000);
    _taskRecord.upload_progress = -1;
    _taskRecord.upload_status = 1;
    _taskRecord.upload_show_text = [NSString stringWithFormat:@"%d %@", 100, @"%"];
    [(NSObject *)self.delegate performSelectorOnMainThread:@selector(merchantTaskDidFinish:) withObject:self waitUntilDone:NO];
    usleep(1000*5000);
    _taskRecord.upload_progress = -1;
    _taskRecord.upload_status = 2;
    _taskRecord.upload_show_text = [NSString stringWithFormat:@"%d %@", 100, @"%"];
    [(NSObject *)self.delegate performSelectorOnMainThread:@selector(merchantTaskDidFinish:) withObject:self waitUntilDone:NO];
    usleep(1000*5000);
    [self sysPicInfo:@"" withSysText:@""];
    return @"";
}

-(NSString *)sysPicInfo:(NSString *)sysUrl withSysText:(NSString *)sysText{
    _taskRecord.upload_progress = 6;
    _taskRecord.upload_status = 2;
    [(NSObject *)self.delegate performSelectorOnMainThread:@selector(merchantTaskDidFinish:) withObject:self waitUntilDone:NO];
    NSLog(@"开始同步图片");
    usleep(1000*5000);
    _taskRecord.upload_progress = 8;
    _taskRecord.upload_status = 3;
    [(NSObject *)self.delegate performSelectorOnMainThread:@selector(merchantTaskDidFinish:) withObject:self waitUntilDone:NO];
    return @"";
}



@end

上面的数据是用来测试的。

 

多线程的概念和原理

概念:一个程序开启多条线程,每条线程可以并行(同时)执行不同的任务

原理:(1)多个线程并发执行,其本质就是CPU快速地在多条线程之间切换。(2)当CPU调度线程的时间足够快,就会造成多线程并发执行的假象。

import <BaiduMapAPI_Location/BMKLocationService.h> //定位服务

3、数据库设计

首先是表结构设计,如下:

 

//
//  UploadTable.h
//  UploadManager
//
//  Created by 张杰 on 15/5/8.
//  Copyright (c) 2015年 张杰. All rights reserved.
//

#import 

@interface UploadTable : NSObject

@property (nonatomic, strong) NSString *upload_id;//协议、工单、临时工单的ID
@property (nonatomic, strong) NSString *upload_name;//协议、工单、临时工单的商户名称
@property (nonatomic, strong) NSString *upload_type;//协议:0;工单:1;临时工单:2
@property (nonatomic, strong) NSString *upload_text;//文字信息格式json
@property (nonatomic, strong) NSString *upload_img_name;//图片的名字格式json
@property (nonatomic, strong) NSString *upload_img_sys;//图片同步数据
@property int upload_progress;//UI的同步状态  上传进度:-1;未处理:0;文字上传中:1;文字上传失败:2;图片未上传:3;图片上传中:4;图片上传失败:5;图片同步中:6;图片同步失败:7;上传完成8
@property int upload_status;//线程中使用  0:未处理 1:文字已上传  2:图片已上传  3:同步成功
@property (nonatomic, strong) NSString *upload_show_text;//上传显示文字的进度
@property (nonatomic, getter = isStarting) BOOL starting; // 任务是否正在进行

@end



//
//  UploadTable.m
//  UploadManager
//
//  Created by 张杰 on 15/5/8.
//  Copyright (c) 2015年 张杰. All rights reserved.
//

#import "UploadTable.h"

@implementation UploadTable

@synthesize upload_id = _upload_id;
@synthesize upload_name = _upload_name;
@synthesize upload_type = _upload_type;
@synthesize upload_text = _upload_text;
@synthesize upload_img_name = _upload_img_name;
@synthesize upload_img_sys = _upload_img_sys;
@synthesize upload_progress = _upload_progress;
@synthesize upload_status = _upload_status;
@synthesize upload_show_text = _upload_show_text;
@synthesize starting = _starting;

-(BOOL)isStarting{
    return _starting;
}

@end

数据库操作:

 

 

//
//  DBHelper.h
//  UploadManager
//
//  Created by 张杰 on 15/5/8.
//  Copyright (c) 2015年 张杰. All rights reserved.
//

#import 
#import "FMDatabase.h"
#import "DBHelperOperation.h"

@interface DBHelper : NSObject 

+(DBHelper*) getInstance;

@end



//
//  DBHelper.m
//  UploadManager
//  创建数据库,表结构
//  Created by 张杰 on 15/5/8.
//  Copyright (c) 2015年 张杰. All rights reserved.
//

#import "DBHelper.h"

@interface DBHelper(){

    FMDatabase *db;
    //数据库表结构字段
    NSString *TABLE_NAME;//表名字
    NSString *UPLOAD_ID;//协议、工单、临时工单的ID
    NSString *UPLOAD_NAME;//协议、工单、临时工单的商户名称
    NSString *UPLOAD_TYPE;//协议:0;工单:1;临时工单:2
    NSString *UPLOAD_TEXT;//文字信息格式json
    NSString *UPLOAD_IMG_NAME;//图片的名字格式json
    NSString *UPLOAD_IMG_SYS;//图片同步数据
    NSString *UPLOAD_PROGRESS;//UI的同步状态  未处理:0;文字上传中:1;文字上传失败:2;图片未上传:3;图片上传中:4;图片上传失败:5;图片同步中:6;图片同步失败:7
    NSString *UPLOAD_STATUS;//线程中使用  0:未处理  1:文字已更新 2:文字已上传  3:图片已上传  4:同步成功
}


@end

@implementation DBHelper


+(DBHelper*) getInstance
{
    static DBHelper *instance = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        instance = [[self alloc] init];
        [instance onCreate];
        [instance onCreateTable];
        NSLog(@"init");
    });
    return instance;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        TABLE_NAME = @"table_upload_status";
        UPLOAD_ID = @"upload_id";
        UPLOAD_NAME = @"upload_name";
        UPLOAD_TYPE = @"upload_type";
        UPLOAD_TEXT = @"upload_text";
        UPLOAD_IMG_NAME = @"upload_img_name";
        UPLOAD_IMG_SYS = @"upload_img_sys";
        UPLOAD_PROGRESS = @"upload_progress";
        UPLOAD_STATUS = @"upload_status";
    }
    return self;
}

-(void)onCreate{
    NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    NSString *dbPath   = [docsPath stringByAppendingPathComponent:@"umpad_upload_manager.db"];
    db  = [FMDatabase databaseWithPath:dbPath];
}

-(BOOL)onCreateTable{
    if ([db open]) {
        NSString *sqlCreateTable = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS  '%@' (id INTEGER PRIMARY KEY AUTOINCREMENT, '%@' TEXT, '%@' TEXT, '%@' TEXT, '%@' TEXT, '%@' TEXT, '%@' TEXT, '%@' INTEGER, '%@' INTEGER)", TABLE_NAME, UPLOAD_ID, UPLOAD_NAME, UPLOAD_TYPE, UPLOAD_TEXT, UPLOAD_IMG_NAME, UPLOAD_IMG_SYS, UPLOAD_PROGRESS, UPLOAD_STATUS];
        [db beginTransaction];
        BOOL res = [db executeUpdate: sqlCreateTable];
        if (res) {
            NSLog(@"创建表成功");
        }else{
            NSLog(@"创建表失败");
        }
        [db commit];
        [db close];
        return res;
    }
    return FALSE;
}

-(BOOL)onUpgrade{
    return FALSE;
}

//插入一条数据
-(BOOL) insertOneData : (UploadTable*) table{
    if ([db open]) {
        NSString *insertSql= [NSString stringWithFormat:
                              @"INSERT INTO '%@' ('%@', '%@', '%@', '%@', '%@', '%@', '%@', '%@') VALUES ('%@', '%@', '%@', '%@', '%@', '%@', '%d', '%d')",
                              TABLE_NAME, UPLOAD_ID, UPLOAD_NAME, UPLOAD_TYPE, UPLOAD_TEXT, UPLOAD_IMG_NAME, UPLOAD_IMG_SYS, UPLOAD_PROGRESS, UPLOAD_STATUS, table.upload_id, table.upload_name, table.upload_type, table.upload_text, table.upload_img_name, table.upload_img_sys, table.upload_progress, table.upload_status];
        [db beginTransaction];
        BOOL res = [db executeUpdate:insertSql];
        if (res) {
            NSLog(@"insertOneData成功");
        }else{
            NSLog(@"insertOneData失败");
        }
        [db commit];
        [db close];
        return res;
    }
    return FALSE;
}

//更新一条数据
-(BOOL) uploadOneData : (UploadTable*) table{
    if ([db open]) {
        NSString *updateSql = [NSString stringWithFormat:@"UPDATE '%@' SET '%@' = '%@', '%@' = '%@', '%@' = '%@', '%@' = '%@','%@' = '%d', '%@' = '%d', WHERE '%@' = '%@'", TABLE_NAME, UPLOAD_NAME, table.upload_name, UPLOAD_TEXT, table.upload_text, UPLOAD_IMG_NAME, table.upload_img_name, UPLOAD_IMG_SYS, table.upload_img_sys, UPLOAD_PROGRESS, table.upload_progress, UPLOAD_STATUS, table.upload_status, UPLOAD_ID, table.upload_id];
        [db beginTransaction];
        BOOL res = [db executeUpdate:updateSql];
        [db commit];
        [db close];
        return res;
    }
    return FALSE;
}

//删除一条数据
-(BOOL) deleteOneData : (NSString*) upload_id{
    if ([db open]) {
        NSString *deleteSql = [NSString stringWithFormat:@"DELETE FROM '%@' WHERE '%@' = '%@'", TABLE_NAME, UPLOAD_ID, upload_id];
        [db beginTransaction];
        BOOL res = [db executeUpdate:deleteSql];
        [db commit];
        [db close];
        return res;
    }
    return FALSE;
}

//删除所有数据
-(BOOL) deleteAllData{
    if ([db open]) {
        NSString *deleteAllSql = [NSString stringWithFormat:@"DELETE FROM '%@'", TABLE_NAME];
        [db beginTransaction];
        BOOL res = [db executeUpdate:deleteAllSql];
        [db commit];
        [db close];
        return res;
    }
    return FALSE;
}

//判断当前数据是否存在
-(BOOL) isOneDataExist : (NSString*) upload_id{

    return FALSE;
}

//修改线程使用状态
-(BOOL) modifyUploadStatus : (NSString*) upload_id andStatus : (int)status{
    if ([db open]) {
        NSString *modifyStatus = [NSString stringWithFormat:@"UPDATE '%@' SET '%@' = '%d' WHERE '%@' = '%@'", TABLE_NAME, UPLOAD_STATUS, status, UPLOAD_ID, upload_id];
        [db beginTransaction];
        BOOL res = [db executeUpdate:modifyStatus];
        [db commit];
        [db close];
        return res;
    }
    return FALSE;
}

//修改UI使用状态
-(BOOL) modifyUploadProgressStatus : (NSString *)upload_id andStatus : (int)progressStatus{
    if ([db open]) {
        NSString *modifyProgressStatus = [NSString stringWithFormat:@"UPDATE '%@' SET '%@' = '%d' WHERE '%@' = '%@'", TABLE_NAME, UPLOAD_PROGRESS, progressStatus, UPLOAD_ID, upload_id];
        [db beginTransaction];
        BOOL res = [db executeUpdate:modifyProgressStatus];
        [db commit];
        [db close];
        return res;
    }
    return FALSE;
}

//修改两个状态
-(BOOL) modifyStatusAll : (NSString*)upload_id andStatus : (int)status andProgressStatus : (int)progressStatus{
    if ([db open]) {
        NSString *modifyStatusAll = [NSString stringWithFormat:@"UPDATE '%@' SET '%@' = '%d', '%@' = '%d' WHERE '%@' = '%@'", TABLE_NAME, UPLOAD_PROGRESS, progressStatus, UPLOAD_STATUS, status, UPLOAD_ID, upload_id];
        [db beginTransaction];
        BOOL res = [db executeUpdate:modifyStatusAll];
        [db commit];
        [db close];
        return res;
    }
    return FALSE;
}

//查询一条数据
-(UploadTable*) queryDataByUploadId : (NSString*)upload_id{
    if ([db open]) {
        NSString *queryOneSql = [NSString stringWithFormat:@"SELECT * FROM '%@' WHERE '%@' = '%@'", TABLE_NAME, UPLOAD_ID, upload_id];
        FMResultSet *resultSet = [db executeQuery:queryOneSql];
        if ([resultSet next]) {
            UploadTable *result = [[UploadTable alloc]init];
            result.upload_id = [resultSet stringForColumn:UPLOAD_ID];
            result.upload_name = [resultSet stringForColumn:UPLOAD_NAME];
            result.upload_text = [resultSet stringForColumn:UPLOAD_TEXT];
            result.upload_type = [resultSet stringForColumn:UPLOAD_TYPE];
            result.upload_img_name = [resultSet stringForColumn:UPLOAD_IMG_NAME];
            result.upload_img_sys = [resultSet stringForColumn:UPLOAD_IMG_SYS];
            result.upload_progress = [resultSet intForColumn:UPLOAD_PROGRESS];
            result.upload_status = [resultSet intForColumn:UPLOAD_STATUS];
            return result;
        }
        [db close];
    }
    return nil;
}

//查询所有的数据
-(NSMutableArray*) queryDataAll{
    NSMutableArray *restArray = [[NSMutableArray alloc] init];
    if ([db open]) {
        NSString *queryAllSql = [NSString stringWithFormat:@"SELECT * FROM '%@'", TABLE_NAME];
        FMResultSet *resultSet = [db executeQuery:queryAllSql];
        while ([resultSet next]) {
            UploadTable *result = [[UploadTable alloc]init];
            result.upload_id = [resultSet stringForColumn:UPLOAD_ID];
            result.upload_name = [resultSet stringForColumn:UPLOAD_NAME];
            result.upload_text = [resultSet stringForColumn:UPLOAD_TEXT];
            result.upload_type = [resultSet stringForColumn:UPLOAD_TYPE];
            result.upload_img_name = [resultSet stringForColumn:UPLOAD_IMG_NAME];
            result.upload_img_sys = [resultSet stringForColumn:UPLOAD_IMG_SYS];
            result.upload_progress = [resultSet intForColumn:UPLOAD_PROGRESS];
            result.upload_status = [resultSet intForColumn:UPLOAD_STATUS];
            [restArray addObject:(result)];
        }
        [db close];
    }
    return restArray;
}



@end

在DBHelper中实现了增删改查功能,里面的方法是在协议DBHelperOperation中:

 

 

//
//  DBHelperOperation.h
//  UploadManager
//
//  Created by 张杰 on 15/5/8.
//  Copyright (c) 2015年 张杰. All rights reserved.
//

#import "UploadTable.h"

@protocol DBHelperOperation 

//创建数据
-(void)onCreate;
//创建表
-(BOOL)onCreateTable;
//更新数据库
-(BOOL)onUpgrade;
//插入一条数据
-(BOOL) insertOneData : (UploadTable*) table;
//更新一条数据
-(BOOL) uploadOneData : (UploadTable*) table;
//删除一条数据
-(BOOL) deleteOneData : (NSString*) table;
//删除所有数据
-(BOOL) deleteAllData;
//判断当前数据是否存在
-(BOOL) isOneDataExist : (NSString*) upload_id;
//修改线程使用状态
-(BOOL) modifyUploadStatus : (NSString*) upload_id andStatus : (int)status;
//修改UI使用状态
-(BOOL) modifyUploadProgressStatus : (NSString *)upload_id andStatus : (int)progressStatus;
//修改两个状态
-(BOOL) modifyStatusAll : (NSString*)upload_id andStatus : (int)status andProgressStatus : (int)progressStatus;
//查询一条数据
-(UploadTable*) queryDataByUploadId : (NSString*)upload_id;
//查询所有的数据
-(NSMutableArray*) queryDataAll;

@end

那么了解了这么多,我们学习多线程开发主要是为了什么呢?

import <BaiduMapAPI_Search/BMKPoiSearch.h>//Poi搜索附近

4、UI界面操作

 

 

//
//  ViewController.h
//  UploadManager
//
//  Created by 张杰 on 15/5/14.
//  Copyright (c) 2015年 张杰. All rights reserved.
//

#import 
#import "DBHelper.h"
#import "PendingOperations.h"
#import "MerchantTask.h"
#import "UploadTable.h"
#import "UploadTableCell.h"

@interface ViewController : UITableViewController 

@property (nonatomic, strong) NSMutableArray *tableData; // main data source of controller
@property (nonatomic, strong) PendingOperations *pendingOperations;

@end



//
//  ViewController.m
//  UploadManager
//
//  Created by 张杰 on 15/5/14.
//  Copyright (c) 2015年 张杰. All rights reserved.
//

#import "ViewController.h"

@interface ViewController(){
    DBHelper *dbHelper;
}

@end

@implementation ViewController
@synthesize tableData = _tableData;
@synthesize pendingOperations = _pendingOperations;

- (PendingOperations *)pendingOperations {
    if (!_pendingOperations) {
        _pendingOperations = [[PendingOperations alloc] init];
    }
    return _pendingOperations;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    dbHelper = [DBHelper getInstance];
//    [dbHelper deleteAllData];
//    UploadTable *table1 = [[UploadTable alloc] init];
//    table1.upload_id = @"lskjfsfjsfa";
//    table1.upload_name = @"上海科技有限技术责任公司";
//    table1.upload_type = @"协议";
//    table1.upload_progress = 70;
//    [dbHelper insertOneData:table1];
//    UploadTable *table2 = [[UploadTable alloc] init];
//    table2.upload_id = @"33lk333";
//    table2.upload_name = @"上海榕湖全资子公司回执信息办事处";
//    table2.upload_type = @"工单";
//    table2.upload_progress = 48;
//    [dbHelper insertOneData:table2];
    _tableData = [dbHelper queryDataAll];
}

- (void)viewDidUnload {
    [super viewDidUnload];
}


- (void)didReceiveMemoryWarning {
    [self cancelAllOperations];
    [super didReceiveMemoryWarning];
}

//返回某个节中的行数
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [_tableData count];
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"uploadTableCell";
    UploadTableCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (!cell) {
        cell = [[UploadTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }
    UploadTable *uploadTable = [_tableData objectAtIndex:indexPath.row];
    //    未处理:0;文字上传中:1;文字上传失败:2;图片未上传:3;图片上传中:4;图片上传失败:5;图片同步中:6;图片同步失败:7;图片上传进度:8
    switch (uploadTable.upload_progress) {
        case 0:
            cell.uploadProgress.text = @"未处理";
            break;
        case 1:
            cell.uploadProgress.text = @"文字上传中";
            break;
        case 2:
            cell.uploadProgress.text = @"文字上传失败";
            break;
        case 3:
            cell.uploadProgress.text = @"图片未上传";
            break;
        case 4:
            cell.uploadProgress.text = @"图片上传中";
            break;
        case 5:
            cell.uploadProgress.text = @"图片上传失败";
            break;
        case 6:
            cell.uploadProgress.text = @"图片同步中";
            break;
        case 7:
            cell.uploadProgress.text = @"图片同步失败";
            break;
        case 8:
            cell.uploadProgress.text = @"上传完成";

            break;
        case -1:
            cell.uploadProgress.text = uploadTable.upload_show_text;
            break;
        default:
            break;
    }

    cell.dataName.text = uploadTable.upload_name;
    cell.dataType.text = uploadTable.upload_type;
    cell.upload_id = uploadTable.upload_id;
    [self startOperationsForTaskRecord:uploadTable atIndexPath:indexPath];
    return cell;
}

#pragma mark -
#pragma mark - Operations

- (void)startOperationsForTaskRecord:(UploadTable *)record atIndexPath:(NSIndexPath *)indexPath {

    if (!record.isStarting) {
        [self startTaskingForRecord:record atIndexPath:indexPath];
    }
}

- (void)startTaskingForRecord:(UploadTable *)record atIndexPath:(NSIndexPath *)indexPath {

    if (![self.pendingOperations.uploadInProgress.allKeys containsObject:indexPath]) {
        MerchantTask *merchantTask = [[MerchantTask alloc] initWithTaskRecord:record atIndexPath:indexPath delegate:self];
        [self.pendingOperations.uploadInProgress setObject:merchantTask forKey:indexPath];
        [self.pendingOperations.uploadQueue addOperation:merchantTask];
    }
}

#pragma mark -
#pragma mark - Cancelling, suspending, resuming queues / operations


- (void)suspendAllOperations {
    [self.pendingOperations.uploadQueue setSuspended:YES];
}


- (void)resumeAllOperations {
    [self.pendingOperations.uploadQueue setSuspended:NO];
}


- (void)cancelAllOperations {
    [self.pendingOperations.uploadQueue cancelAllOperations];
}

- (IBAction)upLoadBtn:(id)sender {


}

- (void) merchantTaskDidFinish:(MerchantTask *)uploader{
    // 1: Check for the indexPath of the operation, whether it is a download, or filtration.
    NSIndexPath *indexPath = uploader.indexPathInTableView;
    NSLog(@"upload_id: %@ ; upload_progress: %d",uploader.taskRecord.upload_name, uploader.taskRecord.upload_progress);
    // 2: Get hold of the PhotoRecord instance.
    UploadTable *theRecord = uploader.taskRecord;

    // 3: Replace the updated PhotoRecord in the main data source (Photos array).
    [_tableData replaceObjectAtIndex:indexPath.row withObject:theRecord];

    // 4: Update UI.
    [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    if(uploader.taskRecord.upload_status == 3){//上传成功
        [self.pendingOperations.uploadInProgress removeObjectForKey:indexPath];
        [self.pendingOperations.uploadFinishProgress setObject:uploader forKey:indexPath];
    }
}



@end

5、实现效果:

 

金沙js333娱乐场 1  

 

开发上传管理器 由于项目需要整合多处的上传功能,涉及到的主要有数据库(FMDB),多线程() 1、新建项目,下载依赖库 首先新建一个项目...

简单来说一下多线程的优缺点

优点:能适当地提高程序的执行效率,能适当提高资源利用率(CPU和内存利用率)

缺点:创建多线程是有开销的,包括内存空间和创建时间上的开销,如果开启大量的线程,会导致程序性能降低,线程越多,CPU在调度线程上的开销就越大

import <BaiduMapAPI_Map/BMKAnnotation.h>//标注点的protocol

到底什么是主线程,以及他有什么作用,下面让我们一起探索一下

定义:iOS程序运行后,默认开启一条线程,称为多线程

作用:显示或刷新UI界面,处理UI事件

注意:不要将耗时操作放到主线程,耗时操作会卡死主线程,影响UI界面性能

import <BaiduMapAPI_Map/BMKPointAnnotation.h>//定位点的泡泡

实现多线程的方法主要有哪些?以及他们有哪些特点

NSThread:(偶尔OC)使用更加面向对象,简单易用,可直接操作线程对象

GCD:(经常C)旨在替代NSThread等线程技术,充分利用设备的多核

NSOperation:(经常OC)基于GCD,比GCD多了一些更简单实用的功能,使用更加面向对象

import <BaiduMapAPI_Map/BMKPinAnnotationView.h>//提供类似大头针效果的annotation view

3.内存泄漏的情况下如何调试
1.打开XCode的选项:NSZombieEnabled 僵尸模式(打包时要取消)
2.用XCode的Analyze就能分析到哪里有内存泄露
3.使用Instruments的leaks工具分析使用中出现的内存泄漏
4.什么情况下会使用GCD
(GCD)是Apple开发的一个多核编程的解决方法,在多线程中使用比较多。在网络请求及复杂耗时操作时使用。
5.git和svn的区别
最核心的区别Git是分布式的,而Svn不是分布的。
Git把内容按元数据方式存储,而SVN是按文件。
Git没有一个全局版本号,而SVN有
Git的内容的完整性要优于SVN
Git下载下来后,在OffLine状态下可以看到所有的Log,SVN不可以
SVN的特点是简单,只是需要一个放代码的地方时用是OK的。
Git的特点版本控制可以不依赖网络做任何事情,对分支和合并有更好的支持
5.如何使用block代替target...action
创建分类UIButton+targetBlock 扩展action
6.iOS数据缓存
1.直接写文件方式
2.NSUserDefaults
3.归档操作
4.coreData
5.FMDB
7.谈谈你对响应者链的认识
在IOS中,有响应者链对事件进行响应,所有的响应类都是UIResponder的子类,响应者链是一个由不同对象组成的层次结构,其中的每个对象将依次获得响应事件消息的机会。
8.Runtime机制有没有深入了解过
runtime 是 OC底层的一套C语言的API(引入 或),编译器最终都会将OC代码转化为运行时代码,通过终端命令编译.m 文件:clang -rewrite-objc xxx.m可以看到编译后的xxx.cpp(C++文件)。
比如我们创建了一个对象 [[NSObject alloc]init],最终被转换为几万行代码,截取最关键的一句可以看到底层是通过runtime创建的对象
利用runtime 可以做一些OC不容易实现的功能
动态交换两个方法的实现(特别是交换系统自带的方法)
动态添加对象的成员变量和成员方法
获得某个类的所有成员方法、所有成员变量
9.怎么在手机主界面显示控制app里的音频,更改音量,上一曲下一曲
1.更改音量,有系统的API
2.上下曲的逻辑写在AudioController的音频播放控制单例里的,播放时传入的列表 并记录当前播放的index,上下曲目更换index并从播放数组取audio传入播放类进行播放。
10.使用xib或者stotyboard代码合并的时候遇到冲突是什么样的,怎么解决
http://blog.csdn.net/yuanyuan1314521/article/details/49836381
11.你是怎么使用FMDB的
FMDB是一种第三方的开源库,FMDB就是对SQLite的API进行了封装,加上了面向对象的思想
一 项目中添加libsqlite3库的依赖
导入FMDB源码:
下载FMDB的源代码,将代码文件拖入工程
#import导入FMDB的头文件"FMDatabase.h"
二、FMDB使用
使用FMDB前,需要先了解下3个主要类:
FMDatabase : 一个单一的SQLite数据库,用于执行SQL语句。
FMResultSet :执行查询一个FMDatabase结果集。
FMDatabaseQueue :在多个线程来执行查询和更新时会使用这个类。
一般的FMDB数据库操作有:
创建数据库
打开数据库、关闭数据库
执行更新的SQL语句
执行查询的SQL语句
12.GCD和NSOperation的关系,有什么区别
1.GCD的核心是C语言写的系统服务,执行和操作简单高效,因此NSOperation底层也通过GCD实现,换个说法就是NSOperation是对GCD更高层次的抽象,这是他们之间最本质的区别.因此如果希望自定义任务,建议使用NSOperation;
2.依赖关系,NSOperation可以设置两个NSOperation之间的依赖,第二个任务依赖于第一个任务完成执行,GCD无法设置依赖关系,不过可以通过dispatch_barrier_async来实现这种效果;
3.KVO(键值对观察),NSOperation和容易判断Operation当前的状态(是否执行,是否取消),对此GCD无法通过KVO进行判断;
4.优先级,NSOperation可以设置自身的优先级,但是优先级高的不一定先执行,GCD只能设置队列的优先级,无法在执行的block设置优先级;
5.继承,NSOperation是一个抽象类实际开发中常用的两个类是NSInvocationOperation和NSBlockOperation,同样我们可以自定义NSOperation,GCD执行任务可以自由组装,没有继承那么高的代码复用度;
6.效率,直接使用GCD效率确实会更高效,NSOperation会多一点开销,但是通过NSOperation可以获得依赖,优先级,继承,键值对观察这些优势,相对于多的那么一点开销确实很划算,鱼和熊掌不可得兼,取舍在于开发者自己;
13.微信支付接入流程
一、 填写商户平台所需资料
二、创建一个项目
三、下载微信终端SDK文件
SDK文件包括 libWeChatSDK.a,WXApi.h,WXApiObject.h 三个。
请前往“资源下载页”下载最新SDK包 摘自http://www.jianshu.com/p/af8cbc9d51b0

项目中一般在哪用到多线程?

多线程一般用于耗时操作,如:网络请求、上传,下载文件、读取数据库、文件操作、大循环

什么是线程安全问题?有什么解决方案?

定义:多个线程同时访问同一块资源(例如同一个对象、变量、文件)时,引发的数据错乱和数据安全问题,称为线程安全问题

金沙js333娱乐场,解决方法:1.添加互斥锁;2.互斥锁的使用格式 :@synchronized( 锁对象 ){ //需要锁定的代码};3.加锁的原理:使线程同步执行

FMDB是线程安全的么?

FMDB如果使用FMDatabase类是线程不安全的

使用FMDatabaseQueue是线程安全的

线程通信的概念,如何实现?

概念:一个线程传递数据给另一个线程、一个线程中执行完特定任务后,转到另一个线程继续执行任务

实现方法:

performSelectorOnMainThread和performSelectorOnThread方法

performSelectorInBackground(后台线程中执行)

使用GCD的dispatch方法

GCD内部怎么实现的,使用GCD有什么优势?

实现方式:

1.通过定制任务和将任务添加到队列中来实现GCD的多线程功能

2.GCD会自动将队列中的任务去出来,放到对应的线程中执行

3.任务的取出遵循FIFO原则(先进先出)

优势:

1.会自动利用更多的CPU内核

2.会自动管理线程的生命周期

全局并发队列和使用create函数创建的并发队列有什么区别?

1.全局并发队列在整个程序中本身是默认存在的,并且对应有高优先级,默认优先级,低优先级,后台优先级一共四种并发队列,我们只是选择其中一个来用,而使用create函数创建的并发队列是实打实地从头开始去创建一个队列

2.iOS6之前,使用create函数创建的队列都要进行一次Release,而全局并发队列不需要我们手动Release。但在iOS6之后,GCD已经纳入ARC内存操作中,不需要再进行Release

3.使用栅栏函数时,使用全局并发队列是无效的,只有使用create创建的并发队列才有效(特别需要注意)

GCD中如何控制多线程并发执行时的执行顺序

使用栅栏函数dispatch_barrier_async

GCD除了开线程,还可以用在什么地方?

1.单例:一次函数dispatch_once

2.延迟函数:dispatch_after,可以定义执行任务的线程

3.定时器:dispatch_source_set_event_handler

4.快速迭代:dispatch_apply

GCD快速迭代的定义和作用?

定义:同时开启主线程和子线程并发完成循环操作

作用:大大提高循环操作的效率

GCD中队列组的作用

使用队列组,除了可以开启新的线程,同时还能通过group监听队列中任务的执行情况

如何处理GCD造成的死锁问题

1.将队列改为非主队列

2.将调度方式改为异步调度

NSOperation和GCD的区别?

1.实现机制的区别:

(1).使用这两者执行任务都会由系统自动创建、销毁子线程

(2).GCD底层是基于C语言的,NSOperation则是对GCD的封装,是面向对象的

(3).NSOperation只有两种类型的队列,主队列和非主队列(非主队列既可以是并行的也可以是串行的,默认是并行的)

(4).GCD拥有四种类型的队列 (main, global, create[serial], create[concurrent] )

2.使用上的区别:

(1).GCD的使用更轻量级,而NSOperation作为对象提供了更丰富的API

(2).在NSOperationQueue中,可以随时取消要准备执行的任务,而GCD没法停止已经加入queue的block中的任务

(3).KVO能应用在NSOperation中,以监听一个Operation是否完成或取消,这样能比GCD更加有效地掌控我们执行的后台任务

(4).NSOperation通过继承,可以提高代码的复用度,这比GCD更有自由度和扩展性

(5).同一个并行队列中的任务执行时,我们能够设置NSOperation的priority(优先级),使之按顺序执行,而在GCD中,要使block中的任务实现这个功能,需要大量复杂代码

什么是最大任务并发数?NSOperationQueue中如何操纵队列中的任务?

线程的最大任务并发数:异步执行时同一时间内可以同时执行的操作的最大数

当maxConcurrentOperationCount = 1,只能执行一个操作,队列为串行队列

当maxConcurrentOperationCount = 0,无法执行任何操作

当maxConcurrentOperationCount > 1,队列为并发队列

默认条件下maxConcurrentOperationCount = -1,代表最大并发数没有限制

NSOperationQueue处理A,B,C三个线程,要求执行完A,B后才能执行C,怎么做?

添加依赖关系,AB都依赖C

- (void)operation{

NSOperationQueue*queue = [[NSOperationQueuealloc] init];

NSBlockOperation*opA = [NSBlockOperationblockOperationWithBlock:^{

NSLog(@"A----%@",[NSThreadcurrentThread]); 

 }];

NSBlockOperation*opB = [NSBlockOperationblockOperationWithBlock:^{

NSLog(@"B----%@",[NSThreadcurrentThread]);

 }];

NSBlockOperation*opC = [NSBlockOperationblockOperationWithBlock:^{

NSLog(@"C----%@",[NSThreadcurrentThread]);

 }];

//注意:不能互相依赖

[opC addDependency:opA];

 [opC addDependency:opB];

 [queue addOperation:opA]; 

 [queue addOperation:opB];

 [queue addOperation:opC];

NSLog(@"----end----");

}

有一个需求,需要将N个请求全部完成之后执行某个操作,该如何处理

1.GCD中可以使用栅栏函数或者队列组

2.NSOperation中可以添加依赖关系

本文由js333发布于计算机互联网,转载请注明出处:多线程编程,开发上传管理器金沙js333娱乐场:

关键词:

上一篇:建立IIS服务器默认Web站点的知识学习,详细讲解

下一篇:没有了