Git Product home page Git Product logo

blog's People

Contributors

vtostar avatar

Stargazers

 avatar  avatar

Watchers

 avatar

blog's Issues

iOS开发中常用的优秀第三方框架

1. Mantle

Mantle 让我们能简化 Cocoa 和 Cocoa Touch 应用的 model 层。简单点说,程序中经常要进行网络请求,请求到得一般是 json 字符串,我们一般会建一个 Model 类来存放这些数据。这就要求我们编写一系列的序列化代码,来把 json 转换为 Model 。这很费时间,容易错,不容易修改。 Mantle 很好的解决了这个问题,而且更易用。

2. Masonry

IB 时代,如果你还在用代码绝对布局就太 low 了。随着苹果发布 iPhone6 、 iPhone 6 plus 。 iOS 设备将会出现越来越丰富的屏幕尺寸,我们不可能根据每个尺寸做一套布局。所以,使用 autolayout 就很有必要了。在 storyboard 中,可以非常方便的使用 autolayout ,但是为了更好的协作开发,有些公司依然在手写布局,令人沮丧的是苹果提供的 autolayout 语法晦涩难懂,非常影响效率(你可以在 这里 动态查看 autolayout 的语法)。 Masonry 就是设计来解决复杂的手写 autolayout 。如何优雅的使用 autolayout ,且看 Masonry 。

  • 下载链接:Github地址
  • 参考:使用方法,请看 README
  • Cocoapods集成:pod 'Masonry', '~> 0.6.1'

3. Reachability

移动互联网时代,应该很少有应用是不需要网络连接的吧。监测网络连接状态几乎是必不可少的一部分。 Reachability 可以完美的完成这一任务。

  • 下载链接: github地址

  • 参考:使用方法,请看 README

  • Cocoapods集成:pod 'Reachability', '~> 3.2'

    4. BlocksKit

    BlocksKit绝对是 Objective-C 的知心伴侣,它为 OC 常用类提供了强大的 Block 语法支持,使得编写 OC 代码变得舒适、快速、优雅。反正我是绝对离不开它。

  • 下载链接 github地址

  • 参考: block 使用小结、在 arc 中使用 block 、如何防止循环引用

  • cocoapods集成:pod 'BlocksKit', '~> 2.2.5'

    5. KVOController

    如果你在项目中有使用 KVO ,那么 KVOController 绝对是个好选择。它是 facebook 开源的一个 KVO 增强框架。有以下几个特性:

    • 使用 Blocks 、自定义 Actions 或者 NSKeyValueObserving 回调进行通知
    • 观测者移除时无异常
    • 控制器 dealloc 时隐式的观测者移除
    • 提升使用 NSKeyValueObservingInitial 的性能
    • 线程安全并提供在观测者恢复时额外的保护

还有什么理由不使用 KVOController 呢?

  • 下载链接 github地址

  • 参考:KVOController : facebook 开源的 KVO ( Key-value Observing )工具

  • cocoapods集成:pod 'KVOController', '~> 1.0.3'

    6. MBProgressHUD

    一个老牌、经典的通知组件,如果你们美工没有专门设计等待和通知视图,那就用它吧!

  • 下载链接 github地址

  • 参考:参照README

  • cocoapods集成:pod 'MBProgressHUD', '~> 0.9'

    7. ODRefreshControl

    很多公司都自己设计下拉刷新视图,比如网易新闻 iOS 客户端,下拉的时候会有广告出现。如果你只是需要一个下拉刷新,那么可以考虑 ODRefreshControl ,它是原 iOS6 上的橡皮糖刷新样式,很有意思。现在也很多大的 App 在用,比如虾米音乐和 QQ 客户端。

  • 下载链接 github地址

  • 参考:参照README

  • cocoapods集成:pod 'ODRefreshControl', '~> 1.1.0'

    8. pop

    又是 Facebook 开源的。大名鼎鼎的 pop ,做动画的不二之选。收下它吧。

  • 下载链接 github地址

  • 参考:Facebook Pop 使用指南 popping(pop 的使用实例 )

  • cocoapods集成: pod 'pop', '~> 1.0.7'

9. AFNetworking

不用多解释,Objective-C下第一网络请求库。

  • 下载链接 github地址
  • 参考:参照README
  • cocoapods集成:pod 'AFNetworking', '~> 2.5.0'

简历

个人信息

求职意向

iOS研发工程师

工作经历

XX公司 iOS研发工程师

工作职责:

  • 1、根据公司业务发展需求,负责公司IOS移动应用的框架设计和应用开发;
  • 2、IOS开发完成客户端界面及应用程序设计、开发、发布;
  • 3、负责IOS客户端开发流程的控制及优化,项目进度的管理及把控;
  • 4、参与公司产品架构设计、方案的制定;
  • 5、负责IOS平台框架层面的开发维护以及扩展;
  • 6、跟进IOS的新技术发展,编写设计开发及实现文挡;
  • 7、根据产品功能需求设计并完成软件实现。

项目经验

职业技能

致谢

初级程序员自检手册

初级程序员自检手册

在函数中声明了一些不用的变量;


function sayHello($name)
{
    $time = date('Y-m-d H:i:s');
    $weather = 'what a sunshinny day!';
    echo "Hello $name!";
}

症状:可能编程的时候买的股票刚升职、刚交了女朋友,心情格外的好,随便写上点什么?可能之前做需求变更时,代码逻辑没有删干净?可能在练习打字。

解毒:提交代码库前,自己做review,看能够让自己满意么?如果你真检查了,就是要保留上述代码,那么,恭喜你,做程序员太委屈了你,其实你应该去做产品经理!

只注释不清理代码

例子1

症状:废了好大的劲,最终没有调用。猜测代码逻辑是一开始有用的,但是后续需求调整,从动态请求变成一张静态图片了,做需求的人没有认真看代码逻辑,直接修改了最终展示图片的位置,而没有管其他的逻辑,导致这种空跑逻辑的存在。

解毒:修改别人代码的时候是需要谨小慎微的,但是也不能容忍垃圾代码的存在,拿不准的可以找人结对或者review。没有代码洁癖的程序不是好产品经理!

代码中有死循环

例子1

症状:我中有你,你中有我。相互调用前没有沟通清楚?还是就是一个人写的?死循环调用,直至到达系统设置的最大执行时间或者内存溢出,进程挂掉。

解毒:在加入版本库前走读代码,自检一下,看人脑能跑通么?多问问自己如果出错了怎么办?总不能只考虑正常逻辑吧。

反复调用同一函数


$p = new Person();
$p->name = 'Tom';
$p->sex = 'male';
$p->address = 'balizhuang #1 1-1-101, chaoyang district, beijing, china';
$p->save();

//确保存入db
sleep(3);
$p->save();

症状:数据来的不容易,一定要保障数据的可靠性,要存入db。担心系统忙,万一当时系统真的很忙呢,还是多保存一遍比较稳妥,心理踏实。

解毒:额,这个么,建议你写代码时候桌子上摆个关公再点上三炷香,似乎更靠谱。尝试用系统执行的角度去思考代码的运行状况,或者step by step的进行debug调试,能够帮助我们思考,识别出无用的代码。如果第一次save()报错,那就让他报错好了

捕获异常但是不处理或者改变异常信息


try
{
    $p = new Person();
    $p->name = 'Tom';
    $p->sex = 'male';
    $p->address = 'balizhuang #1 1-1-101, chaoyang district, beijing, china';
    $p->save();
}
catch (Exception $e)
{
    //再次尝试下看db能保存么?
    if (false == $p->save())
    {
        throw new MyException('保存db失败了');
    }   
}

症状:这是上个问题的升级版,也许是想加强对错误的处理,起码再努力看看?实在不成再抛出一个我的异常。捕获异常进行错误重试未尝不可,但是首先要注意是否只捕获了你关心的异常?而不是一揽子全收了,再次失败后,再抛出了一个新的异常,那底层带上来的上下文信息可就被吞并了,上层更无法判断是什么问题了。

解毒:只捕获业务关心的异常,不要吞噬上下文信息。

同步依赖外部系统


function getUser($userName)
{
    $user = getUserByDB($userName);
    //取用户相关微信号
    $api = new WeixinAPI();
    $user->code = $api->callWeixinHttpApi('http://weixin.qq.com/xxxx');
    return $user;
}

症状:在本系统调用过程中,同步调用了外部系统(微信)的远程接口,如果外部服务挂了,接口返回不正常时,本系统也无法正常使用。

解毒:依赖外部服务的功能分成:强依赖,比如这个功能是调用对方提供的接口来打电话,如果对方不可用,本系统即不可用;和弱依赖,比如只是在页面右侧广告位显示下微信的二维码,如果对方不可用,不要影响我方其它业务。

要加入错误捕获或者放入消息队列进行异步处理,不要让其阻断本系统的其它功能。如:


function getUser($userName)
{
    $user = getUserByDB($userName);
    try
    {
        $api = new WeixinAPI();
        $user->code = $api->callWeixinHttpApi('http://weixin.qq.com/xxxx');
    }
    catch (WeixinException $e)
    {
        //add logs here
    }
    return $user;
}

一旦微信不可用,WeixinAPI抛出异常,会导致整个系统也不可用。主动捕获可能发生的异常,不要让其阻碍本系统的正常使用。

命名过于笼统或者随意

症状:HTMLHelper,UserManager,XString... 具体可以参考: xstring.php。在各种helper,manager类中,往往混杂了大量说不清楚,或者职责模棱两可的地方,于是我们发明了粘合剂类,用于填充那些谁也不管的功能。

解毒:粘合剂不是一定不能有,但是要在设计时就考虑清楚其职责,而不是笼统的起一个xxxHelper来放。其他人可不知道你这个到底是干嘛的,也不敢用。久而久之就成了垃圾箱。

进阶:深层次的问题是在面向对象开发过程中的职责不清,到底什么逻辑放到service中,什么逻辑放到实体或者知识类中?可以参考:message系统服务.

推荐阅读:

  • agile
  • clean

书的图片可以点击哦。

提高iOS开发效率的方法和工具

介绍

这篇文章主要是介绍一下在iOS开发中使用到的一些可以提升开发效率的方法和工具。

IDE

首先要说的肯定是IDE了,说到IDE,Xcode不能跑,当然你也可能同时在使用AppCode等其他的IDE,在这里主要介绍Xcode中提升开发效率的方法。

1.善用快捷键

快捷键是开发中必不可少的,当你善于使用快捷键的时候,十指在键盘上飞舞,那画面太美,我不敢想象。

Xcode常用快捷键操作

2.善用快捷键

开发中有一些常用的代码,可以放到代码片段中,然后下次你就可以使用快捷方法来使用这些代码了,给大家看下我的Xcode中部分代码片段:

偷懒小技巧

3.Xcode插件

那些不能错过的Xcode插件
快速Add #import
查看项目的’TODO’,’FIXME’等

你可能想,如果没有我要用的插件怎么办?少年,这个时候就要自己动手丰衣足食了,我想你可以看看这个Xcode6插件开发入门

4.注释

VVDocumenter-Xcode

我是如何收拾代码的

网络数据相关

1.调试接口

Chrome插件
DHC 在线调试接口,支持HTTP和HTTPS。
Postman 一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。

2.JSON 数据编辑

JSONView
JSON 格式化工具

UI相关

1.距离

马克鳗 它有免费和收费2个版本,免费版本可以使用基本功能,感觉还不错。
Pixel Winch 试了一下,比马克鳗好使。

2.图片压缩

tinypng,保质压缩,我感觉还不错,推荐给我们UI和后台,他们用过之后都说好
tinypng批量压缩图片脚本 配套使用更佳。

3.AppIcon

AppIcon只需要UI提供一张1024*1024的图就可以了,具体的icon可以用Prepo生成

两地办公

假设这么一种情况:公司用的是SVN,公司一台公司电脑,家里一台自己电脑,有时候可能想回来后接着敲代码,怎么办?

再假设这么一种情况:公司用的是SVN,产品想实现一种效果,但是你又不确定能不能写出来,所以你可能会纠结要不要在公司项目上改动,怎么办?

如果有上述两种烦恼,那么Github 和 Bitbucket 是您的首选,具体选哪个,这里有一篇对比文章:GitHub vs. Bitbucket 不只是功能不同.

Github

Github上好的开源项目太多,一个一个的star,太慢了,怎么破?

这个其实就是Github的Advanced search功能:

另外Github Advanced Search 可以用来寻找小伙伴哦—— Github Advanced Search猎头大法

iOS 中宏(define)与常量(const)的使用

在iOS开发中,经常用到宏定义或者用const修饰一些数据类型,而很多开发者不知道怎么正确使用,导致项目中乱用宏与const修饰

你能区分下面的吗?知道什么时候用吗?

    #define HSCoder @"哈哈哈"
    NSString *HSCoder = @"哈哈哈";
    extern NSString *HSCoder;
    extern const NSString *HSCoder;
    
    static const NSString *HSCoder = @"哈哈哈";
    
    const NSString *HSCoder = @"哈哈哈";
    NSString const *HSCoder = @"哈哈哈";
    NSString * const HSCoder = @"哈哈哈";

当我们想全局共用一些数据时,可以用宏、变量、常量
宏:

  #define HSCoder @"哈哈哈"  

变量

  NSString *HSCoder = @"哈哈哈";  

常量

  四种写法:
    static const NSString *HSCoder = @"哈哈哈";
    const NSString *HSCoder = @"哈哈哈";
    NSString const *HSCoder = @"哈哈哈";
    NSString * const HSCoder = @"哈哈哈";  

宏与常/变量的选择?

宏:只是在预处理器里进行文本替换,没有类型,不做任何类型检查,编译器可以对相同的字符串进行优化。只保存一份到 .rodata 段。甚至有相同后缀的字符串也可以优化,你可以用GCC 编译测试,”Hello world” 与 “world” 两个字符串,只存储前面一个。取的时候只需要给前面和中间的地址,如果是整形、浮点型会有多份拷贝,但这些数写在指令中,占的只是代码段而已,大量用宏会导致二进制文件变大
变量:共享一块内存空间,就算项目中N处用到,也不会分配N块内存空间,可以被修改
常量:共享一块内存空间,就算项目中N处用到,也不会分配N块内存空间,可以根据const修饰的位置设定能否修改

尽量使用const,在苹果API中就是使用常量多些,如下图:

常量区分

全局常量:不管你定义在任何文件夹,外部都能访问

  NSString *HSCoder = @"哈哈哈";  

例如:
在ViewController定义一个 HSCoder 字符串全局常量:

在AppDelegate中访问:

局部常量:用static修饰后,不能提供外界访问

  static NSString *HSCoder = @"哈哈哈";  

例如:
在ViewController定义一个 HSCoder 字符串局部常量:

编译时报错:

const修饰位置不同,代表什么?

  1.const NSString *HSCoder = @"哈哈哈";
  2.NSString const *HSCoder = @"哈哈哈";
  3.NSString * const HSCoder = @"哈哈哈";  
  1.const NSString *HSCoder = @"哈哈哈";
  "*HSCoder"不能被修改, "HSCoder"能被修改

  2.NSString const *HSCoder = @"哈哈哈";
  "*HSCoder"不能被修改, "HSCoder"能被修改

  3.NSString * const HSCoder = @"哈哈哈";
  "HSCoder"不能被修改,"*HSCoder"能被修改

  注意:1和2其实没什么区别  

结论:const右边的总不能被修改

所以一般我们定义一个常量又不想被修改应该这样:

  NSString * const HSCoder = @"哈哈哈";  

在项目中,定义全局常量,一般会写在一个独立文件里

HSConst.m 定义常量:

HSConst.h 提供外接访问常量:

在AppDelegate中访问:

iOS开发编码建议与编程经验

在开发过程中,我们不仅要去看别人的代码,也要让别人看我们的代码。那么,有一个良好的编码习惯将会非常重要。下面将会罗列使用Objective-C来开发iOS的编码建议。

【1】任意函数长度不得超过50行。(其实很容易就超过50行,这就要考虑代码抽取了。)

【2】任意行代码不能超过80字符。(其实也很容易超过80字符,可以考虑多行显示,比如有多个参数时,可以每个参数放一行。)可以在Xcode中设置超过80个字符的提醒,选中“Page guide at column”.设置完之后就会在代码80个字符处有一条竖线。

【3】在每个方法的定义前留白一行,也就是在方法和方法之间留空一行。

【4】功能相近的方法要放在一起,并推荐使用#pragma mark - ***来导航代码,切分代码块。这样可以方便函数的查找。并且可以使用快捷键control+6 来快速查找方法的位置。

【5】二元运算符和参数之间要有一个空格,如赋值号=左右各留一个空格。

    
self.myString = @"235423rew523452345"; 

【6】一元运算符和参数之间不放置空格,比如!非运算符,&按位与,|按位或。

    
BOOL isOpen = true;  
BOOL isClose = !isOpen;

【7】强制类型转换和参数之间不放置空格。

    
NSString *str3 = (NSString*)self.myString;

【8】长的变量值应该拆分为多行。尤其体现在使用数组或者字典。以下也分别是快速声明数组@[]和字典@{}的方法。

    
NSArray *array = @[@"111",  
                     @"2222222222",  
                     @"3333333",  
                     @"wwwwwwwwwwww"  
                     ];

    
NSDictionary *dict = @{@"name":@"jack",  
                       @"age":@"20",  
                       @"gender":@"female",  
                       @"isMarried":@"false"  
                       };  

【9】尽量使用有意义的名字命名,拒绝使用i,j等无意义字符命名。类的命名首字母大写,其他变量的命名首字符小写,并使用驼峰式分割单词。

【10】尽量减少在代码中直接使用数字常量,而使用宏定义等方式。如:MAX_NUMBER_PHONE替代8等等。这样我们搜索也比较方便。

【11】尽量减少代码中的重复计算,比如代码中多处要使用屏幕宽度,然后计算:[[UIScreenmainScreen] bounds].size.width ,很多次,闲得很繁琐,代码也冗长。不如直接宏定义:

    
 ##define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)

【12】合理使用约定俗成的缩略词:

  • alloc:分配;
  • alt:轮流,交替;
  • app:应用程序;
  • calc:计算;
  • dealloc:销毁、析构;
  • func:函数、方法;
  • horiz:水平的;
  • info:信息;
  • init:初始化;
  • max:最大的;
  • min:最小的;
  • msg:消息;
  • nib:Interface Builder;
  • rect:矩形;
  • temp:暂时的;
  • vert:垂直的;

【13】宏定义全部字母大写。

【14】函数长度不要超过50行,小函数比大函数可读性更强。函数的参数不宜过多,零元函数最好,一元函数也不错,高于三元的函数虚重构。

【15】合理范围内使用链式编程:

    
NSString *myName = [[NSString alloc] init];

但是嵌套不宜超过3层,超过3层需进行重构。

【16】函数调用时所有参数在同一行。如果参数过多,则可以每行一个参数,每个参数以冒号对齐。

【17】对传入参数的保护或者说是否为空的判断,尽量不要使用if(!obj),而使用NSAssert断言来处理。NSAssert是系统定义的宏。

    
NSAssert(myName != nil, @"myName参数为空");

如果条件判断为真,则程序继续执行。
如果判断条件为假,则抛出异常,异常内容为后面定义的字符串。

【18】方法参数名前一般使用"an","the","new"来进行修饰。如:

    
-(void)setPersonInfo:(NSString*)theID theName:(NSString*)theName theAge:(NSInteger*)theAge

【19】if-else超过四层的时候,就要考虑重构,多层的if-else结构很难维护。
【20】当需要一定条件才执行某项操作时,不要将最重要的代码内嵌到if中。
如良好的风格是:

    
- (void) someMethod {  
if(![someOther boolValue]) {  
   return;  
  }  
//最重要的代码写在这里;  
} 

反面例子:

    
- (void) someMethod {  
if([someOther boolValue]) {   
     //重要代码;  
  }  
} 

【21】所有的逻辑块都使用{}花括号包围,就算只是一行代码。

【22】明确指定构造函数,并有适当的注释。

【23】不要在init方法中把变量或者说属性初始化为0或者nil,因为没有必要。

【24】UIView的子类初始化的时候,不要进行任何的布局操作。布局操作应该在layoutSubviews里面做;需要重新布局的时候调用setNeedsLayout,而不要直接调用layoutSubviews。

【25】保持公共API简单,也就是保持.h文件简单。放在.h中声明的函数都是会被公开的,如果根本就没必要对其他类公开,再不要在.h中声明。OC中的方法都是公有方法,没有私有方法一说。

【26】一个文件只实现一个类。同一个文件中不要有多个类。

【27】Protocol单独用一个文件来创建,尽量不要与相关类混在一个文件中。

【28】在类定义中使用到自己定义类的时候,尽量不要在头文件中引入自己定义类的头文件,使用@Class替代。而在实现文件中引入头文件。

【29】布局时尽量使用相对布局,比如使用子View在父View中的相对位置。

【30】代码折叠,这个可能是关于开发效率的,我也写在编码规范中,因为这个很有用。Xcode7默认没有开启代码折叠,如果你的方法体行数很长,看起来会很不方便,此时你就可以把方法“收起来”,一个类中的结构就会很清晰。开启方法如下:Xcode菜单-->Preferences-->Text Editing-->勾选Code folding ribbon.如图

【31】推荐方法的第一个花括号直接跟在方法体后,而不是另起一行,这样可以减少代码行。

【32】推荐方法体中的第一行留空,最后一行不留空,这样一个方法就会比较清晰。如图

但是如果该花括号里面又是一个if,for之类的带花括号的语句块,那么上述的第一行可以不留空。

同样,如果花括号内第一行是注释的话,第一行也可以不留空。注释也起到了分隔代码的作用,看起来比较清晰。

再者,如果花括号内只有一行代码,第一行可以不留空。

【33】block中第一行也要留空,同方法体中的第一行留空,使代码清晰。

【34】代表类方法和实例方法的"+"加号,"-"减号后需要一个空格。这是一个非常小的细节,系统默认的方法都是这样的,我们自己声明或者实现一个方法的时候最好也这样。

【35】这一条有点像编程经验了,就是为解决某个问题估算时间。比如要开发某个功能、调试某个bug、给自己一个时间限制,如果在这期间不能解决问题,那么就去寻求帮助。这既是给自己一个压力,也为了不浪费时间。虽然,这一条其实很难做到,我往往由于不甘心而无限拖延时间去解决问题。

【36】由于提到编程经验,就不得不提到版本控制。务必去学会SVN或者Git,就算你是独立开发,也要学会控制自己的代码,当然,你要经常备份你的代码。

xxxxxx


UIWebView* webView = [[UIWebView alloc] initWithFrame:CGRectZero];
NSString* secretAgent = [webView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];

ARC下 NSString属性什么时候用copy,什么时候用strong?

我们在声明一个NSString属性时,对于其内存相关特性,通常有两种选择(基于ARC环境):strong与copy。那这两者有什么区别呢?什么时候该用strong,什么时候该用copy呢?让我们先来看个例子。

示例

我们定义一个类,并为其声明两个字符串属性,如下所示:

@interface TestStringClass ()
@property (nonatomic, strong) NSString *strongString;
@property (nonatomic, copy) NSString *copyedString;
@end

上面的代码声明了两个字符串属性,其中一个内存特性是strong,一个是copy。下面我们来看看它们的区别。
首先,我们用一个不可变字符串来为这两个属性赋值,

- (void)test {
    NSString *string = [NSString stringWithFormat:@"abc"];
    self.strongString = string;
    self.copyedString = string;
    NSLog(@"origin string: %p, %p", string, &string);
    NSLog(@"strong string: %p, %p", _strongString, &_strongString);
    NSLog(@"copy string: %p, %p", _copyedString, &_copyedString);
}

其输出结果是:

origin string: 0x7fe441592e20, 0x7fff57519a48
strong string: 0x7fe441592e20, 0x7fe44159e1f8
copy string: 0x7fe441592e20, 0x7fe44159e200

我们要以看到,这种情况下,不管是strong还是copy属性的对象,其指向的地址都是同一个,即为string指向的地址。如果我们换作MRC环境,打印string的引用计数的话,会看到其引用计数值是3,即strong操作和copy操作都使原字符串对象的引用计数值加了1。

接下来,我们把string由不可变改为可变对象,看看会是什么结果。即将下面这一句

NSString *string = [NSString stringWithFormat:@"abc"];

改成:

NSMutableString *string = [NSMutableString stringWithFormat:@"abc"];

其输出结果是:

origin string: 0x7ff5f2e33c90, 0x7fff59937a48
strong string: 0x7ff5f2e33c90, 0x7ff5f2e2aec8
copy string: 0x7ff5f2e2aee0, 0x7ff5f2e2aed0

可以发现,此时copy属性字符串已不再指向string字符串对象,而是深拷贝了string字符串,并让_ copyedString对象指向这个字符串。在MRC环境下,打印两者的引用计数,可以看到string对象的引用计数是2,而_copyedString对象的引用计数是1。

此时,我们如果去修改string字符串的话,可以看到:因为_ strongString与string是指向同一对象,所以_ strongString的值也会跟随着改变(需要注意的是,此时_ strongString的类型实际上是NSMutableString,而不是NSString);而_ copyedString是指向另一个对象的,所以并不会改变。

结论

由于NSMutableString是NSString的子类,所以一个NSString指针可以指向NSMutableString对象,让我们的strongString指针指向一个可变字符串是OK的。

而上面的例子可以看出,当源字符串是NSString时,由于字符串是不可变的,所以,不管是strong还是copy属性的对象,都是指向源对象,copy操作只是做了次浅拷贝。

当源字符串是NSMutableString时,strong属性只是增加了源字符串的引用计数,而copy属性则是对源字符串做了次深拷贝,产生一个新的对象,且copy属性对象指向这个新的对象。另外需要注意的是,这个copy属性对象的类型始终是NSString,而不是NSMutableString,因此其是不可变的。

这里还有一个性能问题,即在源字符串是NSMutableString,strong是单纯的增加对象的引用计数,而copy操作是执行了一次深拷贝,所以性能上会有所差异。而如果源字符串是NSString时,则没有这个问题。

所以,在声明NSString属性时,到底是选择strong还是copy,可以根据实际情况来定。不过,一般我们将对象声明为NSString时,都不希望它改变,所以大多数情况下,我们建议用copy,以免因可变字符串的修改导致的一些非预期问题。

参考

关于字符串的内存管理,还有些有意思的东西,可以参考。

1.NSString copy not copying?

2.NSString特性分析学习

3.NSString什么时候用copy,什么时候用strong

代码测试

self.navigationController.navigationBar.barTintColor = [UIColor orangeColor];
self.navigationController.navigationBar.titleTextAttributes = [NSDictionary dictionaryWithObject:[UIColor whiteColor] forKey:NSForegroundColorAttributeName];

改变iOS中的导航栏和状态栏 的背景色和字体颜色

先看效果

这是系统默认的效果

这里写图片描述

这是改变后的效果

这里写图片描述


具体的实现方式:

  • 1.在info.plist添加View controller-based status bar appearance字段并将值设置成NO

    这里写图片描述

  • 2.然后在Appdelegate里面添加:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    [application setStatusBarHidden:NO];
    [application setStatusBarStyle:UIStatusBarStyleLightContent];
    return YES;
    }
    
  • 3.给navigationController设置新的背景色和字体颜色

    self.navigationController.navigationBar.barTintColor = [UIColor orangeColor];
    self.navigationController.navigationBar.titleTextAttributes = [NSDictionary dictionaryWithObject:[UIColor whiteColor] forKey:NSForegroundColorAttributeName];
    

只需要这简单的三步即可实现

此去经年,后会无期

像是一切都戛然而止,

于是把所有留在身后。

谢谢曾经所有的用心和敷衍,

所有的骄傲和卑微,

所有的在乎和辜负,

所有的慷慨和苛刻,

如果不说再见,就一定会再见面,

所以我不说,但把眼泪留在这里。

时光不老,我们不散!

Xcode7 Http请求报错加载不出数据的问题

Xcode7采用HTTP请求时,获取到的NSData数据为空, 所以在调用

  • JSONObjectWithData: 方法时出现错误. 检验http链接可以正常访问. 后来发现在iOS9应用通讯安全策略进行了升级, 已不再支持http这种不安全的协议(What's New in iOS 9.0)

    至于为什么http是不安全的, http是超文本传输协议, 信息采用明文传输, 而https则使用SSL加密传输协议进行传输. 既然服务器的链接并不是我们前端所能决定的, 如果一定要发送http协议的请求, 可以修改当前项目的Info.plist文件来实现:

    在Info.plist中添加:

    当然, 以上方法还是建立在所访问的请求是HTTP类型的基础上, 一劳永逸的方法就是让服务端升级使用TLS 1.2 SSL加密请求的HTTPS协议.

服务器已支持TLS 1.2 SSL ,但iOS9上还是不行,还要进行链接里的适配操作。”那是因为:ATS只信任知名CA颁发的证书,小公司所使用的 self signed certificate,还是会被ATS拦截。对此,建议使用链接中给出的NSExceptionDomains,并将你们公司的域名挂在下面。

参考: iOS9AdaptationTips

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.