ios怎样打开wnvios文件如何打开

游戏评测相关信息
?相关游戏评测文章推荐
热门游戏评测文章推荐
《我叫MT Online》安卓版4月25日14
真实赛车3(Real Racing 3)超级逼
赛车竞速游戏巅峰之作《极品飞车17
真实赛车3无限金币版终于出来了!
安装详细步骤: 步骤一:安装主程
《都市赛车6HD|狂野飙车6:火线追击
今天平版世界小编给
千呼万唤始出来……《植物大战僵尸
游戏简介: 《极品飞车13:变速》
《侠盗猎车手:圣安地列斯 Grand T
游戏评测文章阅读排
CS传奇战队wNv gaming、JZBA确认出战PGL安卓移动办公软件
作者:txseo999
摘要:《PGL天王回归争霸赛》将于12月21日-12月25日在北京工体网鱼网咖电竞馆举办,此季《PGL天王回归争霸赛》将预示着PGL的正式回归,尽管时隔六年,但PGL情怀与热血不减,必将呈现一个众人记忆中一样辉煌的赛事,将为玩家呈现一场超视觉的精彩对决。 本次PGL以最
《PGL天王回归争霸赛》将于12月21日-12月25日在北京工体网鱼网咖电竞馆举办,此季《PGL天王回归争霸赛》将预示着PGL的正式回归,尽管时隔六年,但PGL情怀与热血不减,必将呈现一个众人记忆中一样辉煌的赛事,将为玩家呈现一场超视觉的精彩对决。
本次PGL以最为经典的War3和CS1.6为比赛项目,除了已公布的War3选手阵容,CS战队阵容也备受关注,究竟哪些叱咤风云的传奇劲旅将重回赛场成了广大玩家最热衷的问题。值得高兴的是,wNv gaming和JZBA已确认将出战本次PGL。
wNv gaming成立初期境况不佳,由于个人能力、经验与当时的国内一流战队有着一定的差距,并没有达到预期的高度。之后经过不断的人员调整、吐故纳新,终于造就了中国唯一一支写入世界CS历史的战队。
2005年,踌躇满志的wNv gaming在WEG第三赛季爆发,一举击败多支世界顶尖强队问鼎冠军,次年再次夺得WEG 大师赛的冠军,战队排名也迅速蹿升至世界第一。一时间wNv.gaming成为了全球最热门的CS战队,也让世界知道了中国的wNv.gaming。
Alex(卞正伟)作为当年wNv.gaming队长,曾被称作国内第一战术大师。其冷静的头脑和出色的指挥,是wNv.gaming屡次在国内赛事夺冠的重要武器。正是依靠他的出色表现,使wNv.gaming成为2005年ESWC(电竞世界杯)全球总决赛MVP、年WEG世界冠军、国内CS冠军&大满贯&得主,为中国CS界实现零突破。他被中国数百万CSer尊敬地称为:&中国最出色CS指挥官&。在世界CS界,传奇人物bsl说卞正伟是他见过的最谨慎的领导者。著名电脑硬件厂商BENQ还专门推出了以他的ID号命名的限量外设。2013年入选WCG中国区名人堂。而现在他和昔日的队友sakula以教练和解说的身份依然活跃在CSGO界,成为了业界传奇。
此次Alex带领wNv.gaming重新披上wNv的战袍征战PGL天王回归争霸赛CS1.6项目,阵容豪华,值得期待。
2007年,由锦州市电子竞技协会牵头,组建了辽宁省首家职业电子竞技俱乐部&锦州博爱&(JZBA),同年开始参加由国家体育总局主办的CEG全国电子竞技运动会,成绩优秀。多年来,持续不断参加WCG,ESWC,IEF,CEG等国际级和国家级赛事,向国家队和各职业俱乐部输出过多名优秀选手,并在各级比赛中也取得了不俗的战绩。
JZBA在2008年由于国内环境原因一度解散,随后在2008年年底进行了重组。而这支重获新生的队伍在年底再次找回了自己的位置,连续在两站CEG赛事上击败了Savage、KangTa领衔的wNv,拿到一个冠军和一个亚军,加之先前这支队伍精彩的表现,JZBA在年末成功挤身三甲。
JZBA此次参赛的队长FAINT(鞠明远),从2001年就开始接触CS, 2004年进入职业圈,这次在PGL天王争霸赛上会带领他的队员们带来怎么样的精彩表现确实值得期待。
时隔多年,wNv gaming和JZBA两支传奇豪门的实力是否依旧,请与PGL一同见证!
(责任编辑:管理员)
软件名称:Quickoffice 安卓移动办公软件
软件类型:电子办公
软件大小:12.64 MB
------分隔线----------------------------
转载教程《CS传奇战队wNv gaming、JZBA确认出战PGL安卓移动办公软件》请注明出处:安卓在线www.androidonline.net 谢谢!
◎ 用户评论
◎ 阅读说明READ EXPLANATION
推荐使用第三方专业下载工具下载本站软件,使用豌豆荚,360安全安装,91助手安装本站软件。
如果这个软件总是不能下载的请点击报告错误,谢谢合作!!
下载本站资源,如果服务器暂不能下载请过一段时间重试!
如果遇到什么问题,请到本站论坛去咨寻,我们将在那里提供更多 、更好的资源!
本站提供的一些商业软件是供学习研究之用,如用于商业用途,请购买正版。4367人阅读
iOS学习(14)
iOS代码块Block
代码块Block是苹果在iOS4开始引入的对C语言的扩展,用来实现匿名函数的特性,Block是一种特殊的数据类型,其可以正常定义变量、作为参数、作为返回值,特殊地,Block还可以保存一段代码,在需要的时候调用,目前Block已经广泛应用于iOS开发中,常用于GCD、动画、排序及各类回调
注: Block的声明与赋值只是保存了一段代码段,必须调用才能执行内部代码
Block变量的声明、赋值与调用
Block变量的声明
Block变量的声明格式为: 返回值类型(^Block名字)(参数列表);
void(^aBlock)(NSString *x, NSString *y);
void(^aBlock)(NSString *, NSString *);
注: ^被称作”脱字符”
Block变量的赋值
Block变量的赋值格式为: Block变量 = ^(参数列表){函数体};
aBlock = ^(NSString *x, NSString *y){
NSLog(@"%@ love %@", x, y);
注: Block变量的赋值格式可以是: Block变量 = ^返回值类型(参数列表){函数体};,不过通常情况下都将返回值类型省略,因为编译器可以从存储代码块的变量中确定返回值的类型
声明Block变量的同时进行赋值
int(^myBlock)(int) = ^(int num){
return num * 7;
void(^aVoidBlock)() = ^{
NSLog(@"I am a aVoidBlock");
Block变量的调用
aBlock(@"Li Lei",@"Han Meimei");
NSLog(@"result = %d", myBlock(9));
aVoidBlock();
使用typedef定义Block类型
在实际使用Block的过程中,我们可能需要重复地声明多个相同返回值相同参数列表的Block变量,如果总是重复地编写一长串代码来声明变量会非常繁琐,所以我们可以使用typedef来定义Block类型
typedef void(^SayHello)();
SayHello hello = ^(){
NSLog(@"hello");
Block作为函数参数
Block作为C函数参数
void useBlockForC(int(^aBlock)(int, int))
NSLog(@"result = %d", aBlock(300,200));
int(^addBlock)(int, int) = ^(int x, int y){
return x+y;
useBlockForC(addBlock);
useBlockForC(^(int x, int y) {
return x+y;
Block作为OC函数参数
- (void)useBlockForOC:(int(^)(int, int))aBlock
NSLog(@"result = %d", aBlock(300,200));
int(^addBlock)(int, int) = ^(int x, int y){
return x+y;
[self useBlockForOC:addBlock];
[self useBlockForOC:^(int x, int y){
return x+y;
使用typedef简化Block
typedef int(^MyBlock)(int, int);
- (void)useBlockForOC:(MyBlock)aBlock
NSLog(@"result = %d", aBlock(300,200));
MyBlock addBlock = ^(int x, int y){
return x+y;
[self useBlockForOC:addBlock];
[self useBlockForOC:^(int x, int y){
return x+y;
Block内访问局部变量
在Block中可以访问局部变量
int global = 100;
void(^myBlock)() = ^{
NSLog(@"global = %d", global);
myBlock();
在声明Block之后、调用Block之前对局部变量进行修改,在调用Block时局部变量值是修改之前的旧值
int global = 100;
void(^myBlock)() = ^{
NSLog(@"global = %d", global);
global = 101;
myBlock();
在Block中不可以直接修改局部变量
int global = 100;
void(^myBlock)() = ^{
global ++;
NSLog(@"global = %d", global);
myBlock();
注: 原理解析,通过clang命令将OC转为C++代码来查看一下Block底层实现,clang命令使用方式为终端使用cd定位到main.m文件所在文件夹,然后利用clang -rewrite-objc main.m将OC转为C++,成功后在main.m同目录下会生成一个main.cpp文件
void(^myBlock)() = ^{
NSLog(@"global = %d", global);
void(*myBlock)() = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, global));
void(*myBlock)() = &__main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA, global);
struct __main_block_impl_0 {
struct __block_
struct __main_block_desc_0* D
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _global, int flags=0) : global(_global) {
impl.isa = &_NSConcreteStackB
impl.Flags =
impl.FuncPtr =
((void (*)(__block_impl *))((__block_impl *)myBlock)-&FuncPtr)((__block_impl *)myBlock);
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
int global = __cself-&
NSLog((NSString *)&__NSConstantStringImpl__var_folders_6y_vkd9wnv13pz6lc_h8phss0jw0000gn_T_main_d5d9eb_mi_0, global);
Block内访问__block修饰的局部变量
在局部变量前使用下划线下划线block修饰,在声明Block之后、调用Block之前对局部变量进行修改,在调用Block时局部变量值是修改之后的新值
__block int global = 100;
void(^myBlock)() = ^{
NSLog(@"global = %d", global);
global = 101;
myBlock();
在局部变量前使用下划线下划线block修饰,在Block中可以直接修改局部变量
__block int global = 100;
void(^myBlock)() = ^{
global ++;
NSLog(@"global = %d", global);
myBlock();
注: 原理解析,通过clang命令将OC转为C++代码来查看一下Block底层实现
void(^myBlock)() = ^;
void())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, (__Block_byref_global_0 *)&global, ));
Block内访问全局变量
在Block中可以访问全局变量
int global = 100;
void(^myBlock)() = ^{
NSLog(@"global = %d", global);
myBlock();
在声明Block之后、调用Block之前对全局变量进行修改,在调用Block时全局变量值是修改之后的新值
int global = 100;
void(^myBlock)() = ^{
NSLog(@"global = %d", global);
global = 101;
myBlock();
在Block中可以直接修改全局变量
int global = 100;
void(^myBlock)() = ^{
global ++;
NSLog(@"global = %d", global);
myBlock();
注: 原理解析,通过clang命令将OC转为C++代码来查看一下Block底层实现
void(^myBlock)() = ^{
NSLog(@"global = %d", global);
void(*myBlock)() = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));
void(*myBlock)() = &__main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA);
struct __main_block_impl_0 {
struct __block_
struct __main_block_desc_0* D
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) {
impl.isa = &_NSConcreteStackB
impl.Flags =
impl.FuncPtr =
((void (*)(__block_impl *))((__block_impl *)myBlock)-&FuncPtr)((__block_impl *)myBlock);
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
NSLog((NSString *)&__NSConstantStringImpl__var_folders_6y_vkd9wnv13pz6lc_h8phss0jw0000gn_T_main_f35954_mi_0, global);
Block内访问静态变量
在Block中可以访问静态变量
static int global = 100;
void(^myBlock)() = ^{
NSLog(@"global = %d", global);
myBlock();
在声明Block之后、调用Block之前对静态变量进行修改,在调用Block时静态变量值是修改之后的新值
static int global = 100;
void(^myBlock)() = ^{
NSLog(@"global = %d", global);
global = 101;
myBlock();
在Block中可以直接修改静态变量
static int global = 100;
void(^myBlock)() = ^{
global ++;
NSLog(@"global = %d", global);
myBlock();
注: 原理解析,通过clang命令将OC转为C++代码来查看一下Block底层实现
void(^myBlock)() = ^{
NSLog(@"global = %d", global);
void(*myBlock)() = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, &global));
void(*myBlock)() = &__main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA, &global);
struct __main_block_impl_0 {
struct __block_
struct __main_block_desc_0* D
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int *_global, int flags=0) : global(_global) {
impl.isa = &_NSConcreteStackB
impl.Flags =
impl.FuncPtr =
((void (*)(__block_impl *))((__block_impl *)myBlock)-&FuncPtr)((__block_impl *)myBlock);
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
int *global = __cself-&
NSLog((NSString *)&__NSConstantStringImpl__var_folders_6y_vkd9wnv13pz6lc_h8phss0jw0000gn_T_main_4d124d_mi_0, (*global));
Block在MRC及ARC下的内存管理
Block在MRC下的内存管理
默认情况下,Block的内存存储在栈中,不需要开发人员对其进行内存管理
void(^myBlock)() = ^{
NSLog(@"------");
myBlock();
在Block的内存存储在栈中时,如果在Block中引用了外面的对象,不会对所引用的对象进行任何操作
Person *p = [[Person alloc] init];
void(^myBlock)() = ^{
NSLog(@"------%@", p);
myBlock();
[p release];
如果对Block进行一次copy操作,那么Block的内存会被移动到堆中,这时需要开发人员对其进行release操作来管理内存
void(^myBlock)() = ^{
NSLog(@"------");
myBlock();
Block_copy(myBlock);
// do something ...
Block_release(myBlock);
如果对Block进行一次copy操作,那么Block的内存会被移动到堆中,在Block的内存存储在堆中时,如果在Block中引用了外面的对象,会对所引用的对象进行一次retain操作,即使在Block自身调用了release操作之后,Block也不会对所引用的对象进行一次release操作,这时会造成内存泄漏
Person *p = [[Person alloc] init];
void(^myBlock)() = ^{
NSLog(@"------%@", p);
myBlock();
Block_copy(myBlock);
// do something ...
Block_release(myBlock);
[p release]; // Person对象在这里无法正常被释放,因为其在Block中被进行了一次retain操作
如果对Block进行一次copy操作,那么Block的内存会被移动到堆中,在Block的内存存储在堆中时,如果在Block中引用了外面的对象,会对所引用的对象进行一次retain操作,为了不对所引用的对象进行一次retain操作,可以在对象的前面使用下划线下划线block来修饰
__block Person *p = [[Person alloc] init];
void(^myBlock)() = ^{
NSLog(@"------%@", p);
myBlock();
Block_copy(myBlock);
// do something ...
Block_release(myBlock);
[p release]; // Person对象在这里可以正常被释放
如果对象内部有一个Block属性,而在Block内部又访问了该对象,那么会造成循环引用
@interface Person : NSObject
@property (nonatomic, copy) void(^myBlock)();
@implementation Person
- (void)dealloc
NSLog(@"Person dealloc");
Block_release(_myBlock);
[super dealloc];
Person *p = [[Person alloc] init];
p.myBlock = ^{
NSLog(@"------%@", p);
p.myBlock();
[p release];
@interface Person : NSObject
@property (nonatomic, copy) void(^myBlock)();
- (void)resetB
@implementation Person
- (void)resetBlock
self.myBlock = ^{
NSLog(@"------%@", self);
- (void)dealloc
NSLog(@"Person dealloc");
Block_release(_myBlock);
[super dealloc];
Person *p = [[Person alloc] init];
[p resetBlock];
[p release];
如果对象内部有一个Block属性,而在Block内部又访问了该对象,那么会造成循环引用,解决循环引用的办法是在对象的前面使用下划线下划线block来修饰,以避免Block对对象进行retain操作
@interface Person : NSObject
@property (nonatomic, copy) void(^myBlock)();
@implementation Person
- (void)dealloc
NSLog(@"Person dealloc");
Block_release(_myBlock);
[super dealloc];
__block Person *p = [[Person alloc] init];
p.myBlock = ^{
NSLog(@"------%@", p);
p.myBlock();
[p release];
@interface Person : NSObject
@property (nonatomic, copy) void(^myBlock)();
- (void)resetB
@implementation Person
- (void)resetBlock
__block Person *p = self;
self.myBlock = ^{
NSLog(@"------%@", p);
- (void)dealloc
NSLog(@"Person dealloc");
Block_release(_myBlock);
[super dealloc];
Person *p = [[Person alloc] init];
[p resetBlock];
[p release];
Block在ARC下的内存管理
在ARC默认情况下,Block的内存存储在堆中,ARC会自动进行内存管理,程序员只需要避免循环引用即可
void(^myBlock)() = ^{
NSLog(@"------");
myBlock();
在Block的内存存储在堆中时,如果在Block中引用了外面的对象,会对所引用的对象进行强引用,但是在Block被释放时会自动去掉对该对象的强引用,所以不会造成内存泄漏
Person *p = [[Person alloc] init];
void(^myBlock)() = ^{
NSLog(@"------%@", p);
myBlock();
如果对象内部有一个Block属性,而在Block内部又访问了该对象,那么会造成循环引用
@interface Person : NSObject
@property (nonatomic, copy) void(^myBlock)();
@implementation Person
- (void)dealloc
NSLog(@"Person dealloc");
Person *p = [[Person alloc] init];
p.myBlock = ^{
NSLog(@"------%@", p);
p.myBlock();
@interface Person : NSObject
@property (nonatomic, copy) void(^myBlock)();
- (void)resetB
@implementation Person
- (void)resetBlock
self.myBlock = ^{
NSLog(@"------%@", self);
- (void)dealloc
NSLog(@"Person dealloc");
Person *p = [[Person alloc] init];
[p resetBlock];
如果对象内部有一个Block属性,而在Block内部又访问了该对象,那么会造成循环引用,解决循环引用的办法是使用一个弱引用的指针指向该对象,然后在Block内部使用该弱引用指针来进行操作,这样避免了Block对对象进行强引用
@interface Person : NSObject
@property (nonatomic, copy) void(^myBlock)();
@implementation Person
- (void)dealloc
NSLog(@"Person dealloc");
Person *p = [[Person alloc] init];
__weak typeof(p) weakP =
p.myBlock = ^{
NSLog(@"------%@", weakP);
p.myBlock();
@interface Person : NSObject
@property (nonatomic, copy) void(^myBlock)();
- (void)resetB
@implementation Person
- (void)resetBlock
__weak Person *weakP = self;
self.myBlock = ^{
NSLog(@"------%@", weakP);
- (void)dealloc
NSLog(@"Person dealloc");
Person *p = [[Person alloc] init];
[p resetBlock];
Block在ARC下的内存管理的官方案例
在MRC中,我们从当前控制器采用模态视图方式present进入MyViewController控制器,在Block中会对myViewController进行一次retain操作,造成循环引用
MyViewController *myController = [[MyViewController alloc] init];
pletionHandler =
^(NSInteger result) {
[myController dismissViewControllerAnimated:YES completion:nil];
[self presentViewController:myController animated:YES completion:^{
[myController release];
在MRC中解决循环引用的办法即在变量前使用下划线下划线block修饰,禁止Block对所引用的对象进行retain操作
__block MyViewController *myController = [[MyViewController alloc] init];
pletionHandler =
^(NSInteger result) {
[myController dismissViewControllerAnimated:YES completion:nil];
[self presentViewController:myController animated:YES completion:^{
[myController release];
但是上述方法在ARC下行不通,因为下划线下划线block在ARC中并不能禁止Block对所引用的对象进行强引用,解决办法可以是在Block中将myController置空(为了可以修改myController,还是需要使用下划线下划线block对变量进行修饰)
__block MyViewController *myController = [[MyViewController alloc] init];
pletionHandler =
^(NSInteger result) {
[myController dismissViewControllerAnimated:YES completion:nil];
myController =
[self presentViewController:myController animated:YES completion:^{}];
上述方法确实可以解决循环引用,但是在ARC中还有更优雅的解决办法,新创建一个弱指针来指向该对象,并将该弱指针放在Block中使用,这样Block便不会造成循环引用
MyViewController *myController = [[MyViewController alloc] init];
__weak MyViewController *weakMyController = myC
pletionHandler =
^(NSInteger result) {
[weakMyController dismissViewControllerAnimated:YES completion:nil];
[self presentViewController:myController animated:YES completion:^{}];
虽然解决了循环引用,但是也容易涉及到另一个问题,因为Block是通过弱引用指向了myController对象,那么有可能在调用Block之前myController对象便已经被释放了,所以我们需要在Block内部再定义一个强指针来指向myController对象
MyViewController *myController = [[MyViewController alloc] init];
__weak MyViewController *weakMyController = myC
pletionHandler =
^(NSInteger result) {
MyViewController *strongMyController = weakMyC
if (strongMyController)
[strongMyController dismissViewControllerAnimated:YES completion:nil];
// Probably nothing...
[self presentViewController:myController animated:YES completion:^{}];
这里需要补充一下,在Block内部定义的变量,会在作用域结束时自动释放,Block对其并没有强引用关系,且在ARC中只需要避免循环引用即可,如果只是Block单方面地对外部变量进行强引用,并不会造成内存泄漏
注: 关于下划线下划线block关键字在MRC和ARC下的不同
__block在MRC下有两个作用
1. 允许在Block中访问和修改局部变量
2. 禁止Block对所引用的对象进行隐式retain操作
__block在ARC下只有一个作用
1. 允许在Block中访问和修改局部变量
使用Block进行排序
在开发中,我们一般使用数组的如下两个方法来进行排序
不可变数组的方法: - (NSArray *)sortedArrayUsingComparator:(NSComparator)cmptr
可变数组的方法 : - (void)sortUsingComparator:(NSComparator)cmptr
其中,NSComparator是利用typedef定义的Block类型
typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);
其中,这个返回值为NSComparisonResult枚举,这个返回值用来决定Block的两个参数顺序,我们只需在Block中指明不同条件下Block的两个参数的顺序即可,方法内部会将数组中的元素分别利用Block来进行比较并排序
typedef NS_ENUM(NSInteger, NSComparisonResult)
NSOrderedAscending = -1L,
NSOrderedSame,
NSOrderedDescending
我们以Person类为例,对Person对象以年龄升序进行排序,具体方法如下
@interface Student : NSObject
@property (nonatomic, assign) int
@implementation Student
Student *stu1 = [[Student alloc] init];
stu1.age = 18;
Student *stu2 = [[Student alloc] init];
stu2.age = 28;
Student *stu3 = [[Student alloc] init];
stu3.age = 11;
NSArray *array = @[stu1,stu2,stu3];
array = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
Student *stu1 = obj1;
Student *stu2 = obj2;
if (stu1.age & stu2.age)
return NSOrderedD
else if (stu1.age & stu2.age)
return NSOrderedA
return NSOrderedS
李明杰(M了个J)相关技术讲解
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:12877次
排名:千里之外
原创:19篇
(3)(2)(2)(1)(2)(4)(3)(1)(1)Iphone开发(43)
在项目开发的过程中,经常使用静态库文件。例如两个公司之间业务交流,不可能把源代码都发送给另一个公司,这时候将私密内容打包成静态库,别人只能调用接口,而不能知道其中实现的细节。
库是一些没有main函数的程序代码集合。除了静态库,还有动态链接库,他们之间的区别是:静态库可以编译到我们的执行代码中,应用程序可以在没有静态库的环境中运行;动态库不能编译到我们的执行代码中,应用程序必须在有链接库文件的环境下运行。
创建静态库的步骤如下所示,
1、创建Static Library,新建-&Project,选择Static Library,如图,
点击Next,我将Static Library项目名称命名为TimeDate,因为这是我用于处理时间和日期的静态库工程,
2、静态库文件功能的实现细节
创建了静态库Static Library项目之后,Xcode自动为我们创建了TimeDate.h/.m文件,如下图所示,
这时候我们需要在这里面填充一些细节,这里,我想要实现的功能就是将时间戳NSTimeInterval转换成NSString的功能,那么代码的细节如下所示,
TimeDate.h文件
@interface TimeDate : NSObject
- (NSString *)changeToStandardTime:(NSTimeInterval)timeI
TimeDate.m文件
#import "TimeDate.h"
@implementation TimeDate
- (NSString *)changeToStandardTime:(NSTimeInterval)timeInterval
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSString *time = [dateFormatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:timeInterval]];
上面的代码就是将NSTimeInterval转换成NSString,当然这样肯定有考虑不全面的地方,这不是本篇博客的中心内容,读者可以忽略;如果有好的建议请告诉我。
3、编译项目,生成对应的静态库.a文件
首先我们先来看一下编译(Command+B)之前的项目细节,如下图,
这里我们有两个细节需要注意的,①表明现在是选择的是名为pythonhater的真机Device;②libTimeDate.a文件是红色状态,表明这还不是一个实际存在的文件,我们不能在物理磁盘中找到它。只有在编译以后它才是一个实实在在的文件。
这时我们编译项目(Command+B),文件结构如下图,
这时候libTimeDate.a文件变为黑色状态了,表明编译过后它是一个真是存在于物理磁盘的文件,我们右键选择Show in Finder,如下图,出现了它的物理位置,
如图,libTimeDate.a文件隐藏的很深,我们只要知道它存在就好。现在有个问题,我选择的是pythonhater真机Device进行编译的,所以这个libTimeDate.a只能针对iOS真机Device进行使用,而不能在模拟器Simulator上面使用,为了解决这个问题,只要选择模拟器Simulator进行编译,就可以生成对应的模拟器运行需要的libTimeDate.a文件,如下图操作所示,
选择iPhone模拟器编译,然后右键Show in Finder,
上面的Debug-iPhones里面包含iPhone真机所需要的libTimeDate.a静态库文件,而下面的Debug-iPhoneSimulator里面包含的时iPhone模拟器所需要的libTimeDate.a静态库文件。
4、合并静态库
针对真机和模拟器的静态库文件只能在一个平台下面使用,好在我们可以将真机和模拟器上面的静态库文件合并成一个在真机和模拟器都可以使用的静态库文件,通过在终端输入命令即可完成该目的,
完整的命令就是:
lipo -create /Users/mini3/Library/Developer/Xcode/DerivedData/TimeDate-cthodjhjpplctjhfdbhmdcuhwnva/Build/Products/Debug-iphoneos/libTimeDate.a /Users/mini3/Library/Developer/Xcode/DerivedData/TimeDate-cthodjhjpplctjhfdbhmdcuhwnva/Build/Products/Debug-iphonesimulator/libTimeDate.a -output /Users/mini3/Desktop/libTimeDate.a
不过这个是相对自己的路径,读者可以直接将文件拖到终端即可识别完整的路径,如下图所示的方法,
最后在补充上- output /Users/用户名/Desktop/libTimeDate.a,这样就在桌面生成了一个合并过后的libTimeDate.a静态库文件,它可以再真机和模拟器上面同时使用。
5、使用静态库文件,
这时候我们就可以使用自己创建、编译生成的静态库文件了,将TimeDate.h文件和桌面上面的libTimeDate.a文件拖到想要使用的项目中,如下图的目录结构,
为了方便,我直接在AppDelegate中使用创建的静态库文件了,代码如下,
AppDelegate.m文件
#import "AppDelegate.h"
#import "TimeDate.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
TimeDate *timeDate = [[TimeDate alloc] init];
NSTimeInterval timeInterval = ;
NSString *time = [timeDate changeToStandardTime:timeInterval];
NSLog(@"time is %@",time);
return YES;
输出的内容是,
2014-06-25 20:56:15.105 StaticLibrarySample[2517:390790] time is 1973-11-30 05:33:18
这时不管是真机还是模拟器都可以编译通过,正常运行。而使用者只能通过头文件知道我们提供的借口,却不知道实现文件中实现的细节,这有效地隐藏了自己的核心技术和机密内容。
总结:我们开发的就是iOS真机程序,所以可以选择不合并静态库,直接使用真机编译生成的静态库文件进行开发,没有必要为了兼容模拟器而合并静态库文件。当然,如果有强迫症或者公司设备不够,那么还是合并静态库文件吧。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:695422次
积分:7452
积分:7452
排名:第1901名
原创:155篇
转载:102篇
评论:182条
(1)(1)(1)(15)(4)(10)(6)(1)(5)(8)(4)(5)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(2)(11)(5)(3)(4)(9)(4)(6)(5)(11)(3)(2)(15)(9)(11)(7)(5)(1)(7)(3)(3)(5)(8)(9)(3)(2)(6)(1)(10)(1)(5)(2)(5)(2)(2)

我要回帖

更多关于 ios打开压缩文件 的文章

 

随机推荐