当前位置:  编程技术>移动开发
本页文章导读:
    ▪eoe CEO靳岩:从码农到极客的升格之路        eoe CEO靳岩:从码农到极客的升级之路(国内知名Android开发论坛 eoe开发者社区推荐:http://www.eoeandroid.com/)   前天,2013 eoe 移动开发者大会在国家会议中心召开,eoe 开发者社区创始人靳岩在.........
    ▪ 使用@class和#import的细节有关问题        使用@class和#import的细节问题在.h头文件中导入其它头文件可以使用#import语句,从而在该头文件下使用另一个文件中的类和成员,但是我在使用#import语句时却遇到了以下问题: 首先写一个ViewC.........
    ▪ 数据持久化(2)存取沙箱文件       数据持久化(二)存取沙箱文件最近写个小应用,在保存数据时因为数据不是很多所以选择了存取沙箱文件的方法,在写完后写篇博客总结一下该方法的使用。 iPhone应用程序采用沙箱机制.........

[1]eoe CEO靳岩:从码农到极客的升格之路
    来源: 互联网  发布时间: 2014-02-18
eoe CEO靳岩:从码农到极客的升级之路

(国内知名Android开发论坛 eoe开发者社区推荐:http://www.eoeandroid.com/)

 

前天,2013 eoe 移动开发者大会在国家会议中心召开,eoe 开发者社区创始人靳岩在会上分享了自己是如何从一名码农变成了一个极客。

在靳岩看来,码农与极客最大的区别在于码农是以代码行数为生,是在不断的创造代码。而极客则不同,以兴趣为驱动以自我挑战和解决问题为动力,将生产化为创造的一部分。

兴趣是最重要的导师

靳岩是 eoe 开发者社区的创始人,也是极客学院的创始人,在圈内许多人熟悉它的 ID「haiyangjy」,很多人读过他的代码和书却不知道他叫做靳岩。

我叫靳岩,80 后创业者,北邮毕业,最早写服务器代码、写 Android 代码,后来做产品设计、做产品经理,现在什么都做、各方面都做。在创业的过程中写了两本书,有一本书很多人应该都读过。我的微博是“靳岩_eoe”。

靳岩坦诚自己曾经也是一名「码农」,但是他不甘愿做一个码农,现在已经在努力的向极客的方向发展和追寻。

大学里唯一挂的一科室计算机导论……

靳岩并不是一开始就对计算机充满兴趣,大一的时候,他挂了所有计算机学科专业学生都必修的一门专业课《计算机导论》。在分析为什么大学唯一挂掉的一科是专业课的时候,靳岩说:

是因为我能力问题吗?是因为我不聪明吗?是因为我不努力吗?我觉得都不是,现在回头看,我觉得是因为我没有兴趣,我没有学习它的兴趣,这是我大一挂的一门课。

在靳岩的码农生涯中最重要的转这一年在大三,这一年靳岩遇到了时任《计算机体系结构》课程的北邮教授邝坚。邝坚老师的课第一次让靳岩认识到了计算机可以改变一些东西,写代码不仅是编一些计算气或者编一些加减乘除法的东西,它更多的是企业的一种工具,企业怎么样去用它。

当时,邝老师让所有的学生在课上做开放主题演讲,靳岩选择的题目是手机的体系研究,从那时开始靳岩对手机产生了浓厚的兴趣。

我在想手机和计算机到底有什么区别?为什么手机可以打电话而计算机不可以打电话,为什么计算机可以处理很多其它的程序而手机不可以?

后来,靳岩的第一份工作是去手机设计公司做手机设计的研发,后来就真正走到了移动互联网当中。

从码农到极客

有了兴趣,也成功进入移动互联网的靳岩并没有立刻就风生水起起来。和所有这个专业的学生一样,接触到工作后靳岩反倒迷茫了。在接触到移动开发之后,靳岩发现工作中接触的东西大多都和大学里学的不一样,理解的也不一致。

所以在毕业的一、两年当中我疯狂的学习关于计算机技能方面的知识,而不是基础,基础性的知识大学已经学过了,更多技能方面的知识包括怎么样做服务器端、做前端、写 GS,我也搭建各种服务器,毕业之后非常忙碌,去参加很多的技术圈子、跟很多的技术大牛、技术极客们交流,包括这段时间我认识了 EOE 的另外一位联合创始人姚尚朗,他当时就在 RUBY RAILS 社区中,因为对他特别崇拜,就不停地勾搭他,最后很顺利的参与了他在社区中发动的一个翻译 RUBY RAILS2.0 的开发文档活动,就通过这个机会认识了。

码农的学习似乎从毕业才刚刚开始。

之后的两年,靳岩接触到了 Android 和 iOS,这两个系统对于靳岩的震撼都非常之大。因为当国内的山寨手机还在努力的将体验推到和诺基亚的 N95 一个水平的时候,这两个系统的出现彻底改变了移动应用的体验水平。看到了未来方向的靳岩,很快加入了 Android 应用开发的行列。

让这个举动最终导致了 eoe 移动开发者社区的诞生:

当时国内没有 Android 论坛,也没有中文的 Android 开发资料。我上国外一个论坛,我特别感动的是那个论坛里有一位美国的大学老师,我每次问他问题他都能回答,我特别感动,他主动的建立起一个社区组织,帮助其他人更好的学习 Android,这次经历对我的影响非常深远,我决心在中国我们也要建立这样的社区,因为很多人读英文文档可能有些困难,所以我们也想把国外的一些东西翻译成中文拿到中国跟许多程序员朋友一起分享。想到做到,我们当天就搭建了一个论坛,会员有两个,一个是我另一个是姚尚朗……

从 2009 年走到现在,eoe 的平台已经帮助至少 200 万移动开发者学习 Android、Windows phone、IOS 等在内的移动开发技术。最近我们也推出了 eoe 极客学院,因为是邀请制,所以很多人可能不是很了解。在极客学院中我们也帮助超过 2000 位会员做了一些定制的学习。

我们相信极客,技术成就梦想之美,这是我们极客学院中的一句话。

靳岩的极客精神

在大家注册 eoe 开发者社区时,其实在社区右侧已经有了对极客精神的解读。靳岩认为 eoe 的每个人都是 eoe 极客精神的践行者,也是倡导者,eoe 社区也是一个倡导跟践行 eoe 极客精神的地方。按照靳岩的理解极客精神主要有四点:

  • 成为某个领域的专家

  • 不断是给自己设置挑战并且努力去完美超越

  • 总是寻求更好的解决问题的方式

  • 热爱分享

这四点无论哪一点都是码农难以做到的,因为码农靠代码行数吃饭的,他是不停地重复一些东西,但是他没有更深入的了解你在做的事情。并不愿意超越自我,也不会主动的去寻找问题的解决方式,总是等着问题抛过来才被动解决,更不要提分享。

这么说也许很宽泛,仍然会有生活在水深火热中的码农问:「究竟怎样才能从如同僵尸一般的码农生活中摆脱成为一名极客?」

靳岩也总结了几点,如何更容易的从码农身份转换为极客:

  • 是宽松的工作环境和严格的自我要求

    重要的是化外动力为内动力,让解决问题变成挑战问题。

  • 不吝惜价格的使用好的工具,比如 Google 的一系列工具,DropBox,Github,Evernote,因为好的工具是提升效率十分重要的一个途径

  • D.R.Y,Don't repeat your self

    不要重复自己,不要总是用同一种方式做一件事情,因为这么做的话没有成长。

  • 一定要保持好奇心。

    好奇心在靳岩的成长当中影响非常之大,如果没有一开始对计算机与手机区别的好奇,也许就不会进入移动开发领域。第五,此外多读书多旅行,开阔自己工作以外的视野往往能够对工作产生帮助。

  • 多读书,多旅游。

    观察自己工作的行业与领域以外的东西,能够让人对自己手头熟悉的东西有一次重新的认识。

  • 打造极客关系圈,与圈内的人经常保持沟通,倡导分享精神。

  • 这里我想做一个倡导,我们要爱学习,爱编程,爱咖啡,爱可乐,爱挑战,爱超越自我,爱分享,爱看书,爱猫,爱徒步。我喜欢追寻更优雅解决现有问题的方式,不做码农做极客,所以从今天开始,我们请不要互称对方是码农,我们要做极客。

    最后,靳岩化用了著名人类学家玛格丽特的一句话鼓励更多的人们成为极客:

    永远不要怀疑一小群有思想,肯投入的极客竟能改变世界。事实上,世界正是被这群极客所正在改变的。

    (国内知名Android开发论坛 eoe开发者社区推荐:http://www.eoeandroid.com/)

    6楼u01135291815分钟前兴趣,是最好的老师;极客精神是前进的力量!5楼Super_Eagle昨天 23:00码农与极客的界定,解释的很到位4楼u011352918昨天 18:11一定要保持好奇心!!3楼u011352918昨天 17:23这种精神很值得学习!!期待码农到极客的蜕变!!!2楼u011352918昨天 16:02好文必顶!!1楼gondole昨天 16:01不要重复自己 jiz

        
    [2] 使用@class和#import的细节有关问题
        来源: 互联网  发布时间: 2014-02-18
    使用@class和#import的细节问题

    在.h头文件中导入其它头文件可以使用#import语句,从而在该头文件下使用另一个文件中的类和成员,但是我在使用#import语句时却遇到了以下问题:

    首先写一个ViewController类:

    #import <UIKit/UIKit.h>
    #import "NewViewController.h"
    
    @interface ViewController : UIViewController
    @property (strong, nonatomic) NewViewController *nvc;
    @end

    该类包含了属性变量nvc,其类型为NewViewController类。注意上面导入了NewViewController.h文件。

    另外还有一个NewViewController类:

    #import <UIKit/UIKit.h>
    #import "ViewController.h"
    
    @interface NewViewController : UIViewController
    @property (strong, nonatomic) ViewController *vc;
    @end

    该类包含了属性变量vc,其类型为ViewController类。注意该类的头文件也导入了ViewController.h文件。

    问题出现了:



    在编译时编译器发出无法识别ViewController类和NewViewController类的报错。

    个人看来:原因是ViewController类在声明时定义了一个NewViewController类成员,而该类在声明时又定义了一个ViewController类成员,从而导致了循环定义。ViewController类需要NewViewController类完成定义才能正确实现定义,而NewViewController类又需要ViewController类完成定义才能正确实现定义,最终两者均无法完成接口的声明,编译器发出无法识别两个类的报错。


    解决方法:

    #import <UIKit/UIKit.h>
    
    @class NewViewController;
    
    @interface ViewController : UIViewController
    @property (strong, nonatomic) NewViewController *nvc;
    @end

    #import <UIKit/UIKit.h>
    
    @class ViewController;
    
    @interface NewViewController : UIViewController
    @property (strong, nonatomic) ViewController *vc;
    @end

    将以上两个类的头文件的导入语句改成@class声明就可以了。

    原因是@class只是声明了一个类,关于该类的实现等任何细节编译器暂时不需要理会,从而编译器不会报错或者警告。

    另外要使用这两个类时,必须在.m文件中导入对应的.h头文件。



    在解决问题的过程中在网上查了一些资料,看到了关于@class和#import语句使用的一些细节,发现自己写程序的过程中还是有很多细节是需要注意的。

    下面的内容参考了这个链接:http://blog.sina.com.cn/s/blog_a843a8850101b6a7.html

    很多刚开始学习iOS开发的同学可能在看别人的代码的时候会发现有部分#import操作写在m文件中,而h文件仅仅使用@class进行声明,不禁纳闷起来,为什么不直接把#import放到h文件中呢?

    这是因为h文件在修改后,所有import该h文件的所有文件必须重 新build,因此,如果把#import写在h文件中,import该h文件的文件也就会产生不必要的编译,增加编译时间,特别是在项目文件多的情况 下。想象一下,如果只是修改一个h文件而导致上百个文件不必要的编译,那是一件多么让人纠结的事情。。。

    对于@class只是告诉编译器有这个class,请不要报错或警告,因此不会给编译造成影响。

    什么时候用@class这种方式声明比#import好呢?

    stackoverflow上的高手们给了不少建议:

    Randy Marsh:

    When I develop, I have only three things in mind that never cause me any problems.

  • Import super classes
  • Import parent classes (when you have children and parents)
  • Import classes outside your project (like in frameworks and libraries)
  • For all other classes (subclasses and child classes in my project self), I declare them via forward-class.

     

    Justin:

    Simple answer: You #import or #include when there is a physical dependency. Otherwise, you use forward declarations (@class MONClass ,struct MONStruct , @protocol MONProtocol ).

    Here are some common examples of physical dependence:

    • Any C or C++ value (a pointer or reference is not a physical dependency). If you have aCGPoint as an ivar or property, the compiler will need to see the declaration ofCGPoint .
    • Your superclass.
    • A method you use.

    最后,我建议还是养成良好的import习惯,不要偷懒都把import放在h文件中,无论参与的项目大小,养成良好的编程习惯非常重要。

    下面来说一下#import同class之间的区别

         在ios中我们经常会在.h和.m中引入一些类啊等等一般用的是#import来进行声明,你们可能也见到在.h文件进用@class来声明的,那么#import和@class进行声明 到底有什么的区别呢?下面我来说说

      1.import会包含这个类的所有信息,包括实体变量和方法,而@class只告诉编 译器,声明的类的名称,至于这些类是如何定义的,暂时不用考虑,后面会再告诉你,所以在头文件中如果用@class声明某个类后,在.m的实现中如果用到声明类的具体方法或变量时还得再#import类  

    2.在.h头文件中进行声明时用#import的话,如果100个头文件都#import同一个头件,或者这些文件是依次引用的,如A->B,B->C,C->D,当最开始的那个头文件有变化后进行编译时,后面所有引用它的类都需要重新编译,如果引用最开始的头文件的类很多的话,那么这将耗费大量的时间,而用@class则不会,可能有人会想即然.h只是用@class只是简单的一个声明告编译器有这个类不让其报错,那么.m中要用到引入的类的方法和属性时,不还是要#import头文件一次,是的这个是对的,但编译器编译的时候只编译头文件的,所以你的.m中用#import与编译时间没太大关系

    3.接下来说说什么时候该用@class,什么时候该用#import进行声明,

      (1)一般如果有继承关系的用#import,如B是A的子类那么在B中声明A时用#import

      (2) 另外就是如果有循环依赖关系,如:A->B,B->A这样相互依赖时,如果在两个文件的头文件中用#import分别声明对方,那么就会出现头文件循环利用的错误,这时在头文件中用@class声明就不会出错

     (3)还有就是自定义代理的时候,如果在头文件中想声明代理的话如@interface SecondViewController:UIViewController时应用#import不然的话会出错误,注意XXXXDelegate是自定义的


    其中我比较赞同Randy Marsh的观点,只在以下情况下在.h文件中导入其它类的头文件:

    1.需要使用直接父类super classes

    2.需要在子类中使用父类parent classes(在这里super classes和parent classes的分别应该是在于super classes指的是直接父类,parent classes指的是所有父类,即直接父类,父类的父类等等)

    3.需要使用框架或类库frameworks and libraries中的类,如#import <UIKit/UIKit.h>

    需要补充的是(上文也提到了),如果在ViewController中自定义了委托:

    #import <UIKit/UIKit.h>
    
    @protocol ViewControllerDelegate <NSObject>
    
    @end
    
    @class NewViewController;
    
    @interface ViewController : UIViewController
    @property (strong, nonatomic) NewViewController *nvc;
    @property (weak, nonatomic) id <ViewControllerDelegate> vcDelegate;
    @end

    并且NewViewController要实现该委托:

    #import <UIKit/UIKit.h>
    
    @class ViewController;
    
    @interface NewViewController : UIViewController <ViewControllerDelegate>
    @property (strong, nonatomic) ViewController *vc;
    @end

    那么编译器也会报错:


    单纯的@class无法识别该类中定义的委托,解决办法:

    #import <UIKit/UIKit.h>
    #import "ViewController.h"
    
    // @class ViewController;
    
    @interface NewViewController : UIViewController <ViewControllerDelegate>
    @property (strong, nonatomic) ViewController *vc;
    @end

    导入ViewController.h文件。

    也就是要如果NewViewController要实现ViewController中自定义的委托,那么必须使用#import语句导入ViewController.h文件。


    另外上文也非常强调重复导入头文件带来的效率问题:如果在许多不同的.h文件中大量重复导入同一个.h文件,那么该.h文件的修改将导致引用该类的所有类的头文件都要重新进行编译,这样将大幅影响编译效率。

    因此以后编程的时候必须慎用@class和#import,不要偷懒将所有的.h文件都使用#import语句塞入同一个.h文件中。好的编程习惯将有利于提高整个程序的效率。



        
    [3] 数据持久化(2)存取沙箱文件
        来源: 互联网  发布时间: 2014-02-18
    数据持久化(二)存取沙箱文件

    最近写个小应用,在保存数据时因为数据不是很多所以选择了存取沙箱文件的方法,在写完后写篇博客总结一下该方法的使用。


    iPhone应用程序采用沙箱机制,应用程序位于文件系统的限制部分,其它程序不能访问沙盒中的内容,从而更好地保持程序的安全性和程序与程序之间的相互独立性。


    沙箱(Sandbox)位于/user/applications目录下,其目录结构举例如下:


    Documents目录一般用于存放文档数据。

    Library用于保存程序的配置数据,例如该目录下的Preferences文件夹中的plist文件就保存了NSUserDefaults的首选项设置。

    tmp目录用于保存一些程序临时生成的数据。

    WebViewServive表示该程序执行文件的快捷方式。


    这一次说一说怎样使用writeToFile:atomically:方法将要保存的数据写入Documents目录下的文件当中。

    首先要注意该方法的使用对象范围仅适用于:NSString,NSDate,NSNumber,NSArray,NSDictionary,NSData(以Base-64编码)等类。因此若要进行大规模的数据存取该方法并不适合。

    其实该方法的使用非常简单,可以将其写成一个类并提供保存数据的接口,代码如下:

    看看接口部分:

    @interface FilePersistence : NSObject
    -(BOOL)saveMutableDictionary:(NSMutableDictionary *)mdic toFile:(NSString *)fileName;
    -(BOOL)saveMutableArray:(NSMutableArray *)marray toFile:(NSString *)fileName;
    -(NSMutableDictionary *)loadMutableDictionaryFromFile:(NSString *)fileName;
    -(NSMutableArray *)loadMutableArrayFromFile:(NSString *)fileName;
    @end


    数据保存方法:

    /* 保存可变字典对象到文件中 */
    -(BOOL)saveMutableDictionary:(NSMutableDictionary *)mdic toFile:(NSString *)fileName {
        NSString *filePath = [self getFileDirectoryWithName:fileName];
        NSLog(@"%@", filePath);
        if (filePath) {
            BOOL succeed = [mdic writeToFile:filePath atomically:YES]; // 将数据写入文件中
            if (succeed == NO) {
                NSLog(@"Failed to write");
            }
            return succeed;
        }
        else {
            NSLog(@"Save MutableDictionary Error!");
            return NO;
        }
    }
    
    /* 保存可变数组对象到文件中 */
    -(BOOL)saveMutableArray:(NSMutableArray *)marray toFile:(NSString *)fileName {
        NSString *filePath = [self getFileDirectoryWithName:fileName];
        NSLog(@"%@", filePath);
        if (filePath) {
            BOOL succeed = [marray writeToFile:filePath atomically:YES]; // 将数据写入文件中
            if (succeed == NO) {
                NSLog(@"Failed to write");
            }
            return succeed;
        }
        else {
            NSLog(@"Save MutableArray Error!");
            return NO;
        }
    }



    在这里我只写了保存NSMutableDictionary和NSArray两种对象的写入方法,其它数据类型类似。

    在上面的代码中首先要获取文件路径,调用了以下方法:

    /* 获取文件存放的路径 */
    -(NSString *)getFileDirectoryWithName:(NSString *)fileName {
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); // 获取所有Document文件夹路径
        NSString *documentsDirectory = paths[0]; // 搜索目标文件所在Document文件夹的路径,通常为第一个
        if (!documentsDirectory) {
            NSLog(@"Documents directory not found!");
            return nil;
        }
        return [documentsDirectory stringByAppendingPathComponent:fileName]; // 获取用于存取的目标文件的完整路径
    }

    写入文件保存数据的思路非常简单:通过文件名获取文件路径 —— 写入该路径下的指定文件当中(系统自动建立文件)。

    虽然说是沙箱,那么沙箱和其目录下的文件到底在iOS设备系统的哪个位置呢,个人觉得应该是在磁盘当中,所以这种方法也可以说是将数据写入磁盘中的文件保存。


    获取数据的方法:

    /* 从文件中加载可变字典对象 */
    -(NSMutableDictionary *)loadMutableDictionaryFromFile:(NSString *)fileName {
        NSString *filePath = [self getFileDirectoryWithName:fileName];
        NSLog(@"%@", filePath);
        if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
            NSMutableDictionary *mdic = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath]; // 从文件中获取数据
            if (mdic) {
                return mdic;
            }
            else {
                NSLog(@"mdic == nil");
                return nil;
            }
        }
        else {
            NSLog(@"File not found");
            return nil;
        }
    }
    
    /* 从文件中加载可变数组对象 */
    -(NSMutableArray *)loadMutableArrayFromFile:(NSString *)fileName {
        NSString *filePath = [self getFileDirectoryWithName:fileName];
        if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
            NSMutableArray *marray = [[NSMutableArray alloc] initWithContentsOfFile:filePath]; // 从文件中获取数据
            if (marray) {
                return marray;
            }
            else {
                NSLog(@"marray == nil");
                return nil;
            }
        }
        else {
            NSLog(@"File not found");
            return nil;
        }
    }

    思路是一样的,先获取文件路径,如果该路径下的文件存在,那么从该文件中加载对应的数据。


    在完成以上接口以后,就可以在程序中直接使用FilePersistence类的接口来存取数据了。

    接口部分:

    #import <UIKit/UIKit.h>
    
    @class FilePersistence;
    
    @interface ViewController : UIViewController
    @property (weak, nonatomic) IBOutlet UITextField *tf1;
    @property (weak, nonatomic) IBOutlet UITextField *tf2;
    @property (weak, nonatomic) IBOutlet UITextField *tf3;
    - (IBAction)write:(id)sender;
    - (IBAction)load:(id)sender;
    @property (strong, nonatomic) FilePersistence *filePersistence;
    @property (strong, nonatomic) NSMutableDictionary *mdic;
    @property (strong, nonatomic) UITapGestureRecognizer *tapInView;
    @end

    读写数据的方法实现:

    /* 往沙箱文件内写入数据 */
    - (IBAction)write:(id)sender {
        [mdic setObject:tf1.text forKey:@"key1"];
        [mdic setObject:tf2.text forKey:@"key2"];
        [mdic setObject:tf3.text forKey:@"key3"];
        
        if (!filePersistence) {
            filePersistence = [[FilePersistence alloc] init];
        }
        
        if ([filePersistence saveMutableDictionary:mdic toFile:kFile]) {
            NSLog(@"Writing succeed");
        }
        else {
            NSLog(@"Writing failed");
        }
        
    }
    
    
    /* 从沙箱文件中加载数据 */
    - (IBAction)load:(id)sender {
        if (!filePersistence) {
            filePersistence = [[FilePersistence alloc] init];
        }
        
        NSMutableDictionary *tempDic = [filePersistence loadMutableDictionaryFromFile:kFile];
        if (tempDic) {
            NSString *value1 = tempDic[@"key1"];
            NSString *value2 = tempDic[@"key2"];
            NSString *value3 = tempDic[@"key3"];
            NSLog(@"Loading succeed:");
            NSLog(@"value1 = %@", value1);
            NSLog(@"value2 = %@", value2);
            NSLog(@"value3 = %@", value3);
        }
        else {
            NSLog(@"Loading failed");
        }
    }

    Run一下:



    先Write,再Load后控制台输出如下:

    2013-09-17 18:26:17.095 filePersistence_Demo[741:a0b] /Users/one/Library/Application Support/iPhone Simulator/7.0/Applications/6646F01A-9160-4332-A075-5484B715F578/Documents/mdic.plist
    2013-09-17 18:26:17.096 filePersistence_Demo[741:a0b] Writing succeed
    2013-09-17 18:27:05.671 filePersistence_Demo[741:a0b] /Users/one/Library/Application Support/iPhone Simulator/7.0/Applications/6646F01A-9160-4332-A075-5484B715F578/Documents/mdic.plist
    2013-09-17 18:27:05.672 filePersistence_Demo[741:a0b] Loading succeed:
    2013-09-17 18:27:05.672 filePersistence_Demo[741:a0b] value1 = v1
    2013-09-17 18:27:05.672 filePersistence_Demo[741:a0b] value2 = v2
    2013-09-17 18:27:05.672 filePersistence_Demo[741:a0b] value3 = v3

    为了验证结果,可以打开对应路径下的plist文件看看。

    其中可能要显示一些Mac系统的隐藏文件,方法如下:

    先打开终端,输入下列命令:

    显示Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles YES 

    隐藏Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles NO 

    之后单击Enter键,退出终端。重新启动Finder就可以了。

    重启Finder的方法:

    鼠标单击窗口左上角的苹果标志-->强制退出-->Finder-->重新开启

    或者

    按Command + Option + Esc快捷键,点击Finder,强制退出。

    先找到该文件路径:

    /Users/one/Library/Application Support/iPhone Simulator/7.0/Applications/6646F01A-9160-4332-A075-5484B715F578/Documents/mdic.plist


    打开mdic.plist文件:


    和写入的数据一致,没有问题。


    本来是一个很简单的东西,结果搞了很久,原因是:

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); // 获取所有Document文件夹路径

    在获取Document文件夹路径的语句中,居然把NSDocumentDirectory打成了NSDocumentationDirectory,结果writeToFile:的方法一直返回NO。

    Xcode的代码补全功能很强大,但是过分的依赖也不好,输入代码时一定要看准看准。






        
    最新技术文章:
    ▪Android开发之登录验证实例教程
    ▪Android开发之注册登录方法示例
    ▪Android获取手机SIM卡运营商信息的方法
    ▪Android实现将已发送的短信写入短信数据库的...
    ▪Android发送短信功能代码
    ▪Android根据电话号码获得联系人头像实例代码
    ▪Android中GPS定位的用法实例
    ▪Android实现退出时关闭所有Activity的方法
    ▪Android实现文件的分割和组装
    ▪Android录音应用实例教程
    ▪Android双击返回键退出程序的实现方法
    ▪Android实现侦听电池状态显示、电量及充电动...
    ▪Android获取当前已连接的wifi信号强度的方法
    ▪Android实现动态显示或隐藏密码输入框的内容
    ▪根据USER-AGENT判断手机类型并跳转到相应的app...
    ▪Android Touch事件分发过程详解
    ▪Android中实现为TextView添加多个可点击的文本
    ▪Android程序设计之AIDL实例详解
    ▪Android显式启动与隐式启动Activity的区别介绍
    ▪Android按钮单击事件的四种常用写法总结
    ▪Android消息处理机制Looper和Handler详解
    ▪Android实现Back功能代码片段总结
    ▪Android实用的代码片段 常用代码总结
    ▪Android实现弹出键盘的方法
    ▪Android中通过view方式获取当前Activity的屏幕截...
    ▪Android提高之自定义Menu(TabMenu)实现方法
    ▪Android提高之多方向抽屉实现方法
    ▪Android提高之MediaPlayer播放网络音频的实现方法...
    ▪Android提高之MediaPlayer播放网络视频的实现方法...
    ▪Android提高之手游转电视游戏的模拟操控
     


    站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3