-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
42 lines (28 loc) · 20.4 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><![CDATA[ViewController生命周期认识]]></title>
<url>%2F2017%2F06%2F01%2FviewLife%2F</url>
<content type="text"><![CDATA[本文主要介绍UIViewController生命周期,在视图出现或者消失的时候处理一些必要的逻辑过程。 控制器View的生命周期的方法大致如下: 1234567891011init - 初始化显示过程loadView - 加载视图viewDidLoad - 视图已经加载完毕viewWillAppear - 视图将要显示viewWillLayoutSubviews - 即将布局子控件viewDidLayoutSubviews - 子控件布局完成viewDidAppear - 视图已经显示消失过程viewWillDisappear - 视图即将消失viewDidDisappear - 视图已将消失 当属性被访问的时候判断有没有view,如果存在就直接加载view,如果没有就调用loadview创建view,创建view之前判断loadview有没有自定义,如果自定义Custom Method,那么必须自己创建控制器的View,然后调用ViewDidLoad.若没有自定义loadview呢,就看有没有storyboard或者xib,有的话就加载当前的storyboard或者xib,反之创建一盒空的view.所以loadview是在UIViewController访问view的时候当view为nil的时候调用,loadDidLoad是在界面上初始化操作等,每当view创建完成的时候调用。在实际开发的时候有这两种情况: 1.通过storyboard或者xib创建的控制器,系统会加载view. 2.一般先判断指定的nibname,若没指定就会判断有没有指定的跟控制器类名同名的xib,如果没有任何联系的就会创建一个空的view. 1-(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 多个控制器之间view生命周期当多个控制器之间“切换”的时候,先看下之间的生命周期是如何进行的. 第一个VC:ViewController 第二个VC: testViewController (1)pushViewController ViewController先执行viewWillDisappear,再去执行testViewController的loadView方法,待testViewController的view加载完毕,上一个视图(ViewController)才去完全消失掉,这个时候testViewController就去显示。 1234567891011121314152017-06-01 13:22:49.160004+0800 test[7608:2084362] -[ViewController viewWillDisappear:]2017-06-01 13:22:49.160470+0800 test[7608:2084362] -[testViewController loadView]2017-06-01 13:22:49.160657+0800 test[7608:2084362] -[testViewController viewDidLoad]2017-06-01 13:22:49.161872+0800 test[7608:2084362] -[testViewController viewWillAppear:]2017-06-01 13:22:49.176871+0800 test[7608:2084362] -[testViewController viewWillLayoutSubviews]2017-06-01 13:22:49.177097+0800 test[7608:2084362] -[testViewController viewDidLayoutSubviews]2017-06-01 13:22:49.177326+0800 test[7608:2084362] -[testViewController viewWillLayoutSubviews]2017-06-01 13:22:49.177421+0800 test[7608:2084362] -[testViewController viewDidLayoutSubviews]2017-06-01 13:22:49.682544+0800 test[7608:2084362] -[ViewController viewDidDisappear:]2017-06-01 13:22:49.682798+0800 test[7608:2084362] -[testViewController viewDidAppear:]F viewWillDisappearS viewWillAppearF viewDidDisappearS viewDidAppear 执行顺序:viewWillDisappear -> loadView(test) -> viewDidLoad(test) -> viewWillAppear(test) -> viewDidDisappear -> viewDidAppear(test) (2)popViewController pop和push的过程类似,都是待将要出现的视图出现之后再去消失掉. 123456789102017-06-01 13:44:17.732762+0800 test[7630:2090273] -[testViewController viewWillDisappear:]2017-06-01 13:44:17.733005+0800 test[7630:2090273] -[ViewController viewWillAppear:]2017-06-01 13:44:18.244694+0800 test[7630:2090273] -[testViewController viewDidDisappear:]2017-06-01 13:44:18.244938+0800 test[7630:2090273] -[ViewController viewDidAppear:]2017-06-01 13:44:18.245508+0800 test[7630:2090273] testviewcontroller deallocS viewWillDisappearF viewWillAppearS viewDidDisappearF viewDidAppear 执行顺序:viewWillDisappear(test) -> viewWillAppear -> viewDidDisappear(test) -> viewDidAppear …..testVc dealloc 综上可以得出push和pop的执行顺序是一样的. (3)presentViewController模态 1234567891011121314152017-06-01 13:48:03.876585+0800 test[7633:2091245] -[testViewController loadView]2017-06-01 13:48:03.876899+0800 test[7633:2091245] -[testViewController viewDidLoad]2017-06-01 13:48:03.892119+0800 test[7633:2091245] -[ViewController viewWillDisappear:]2017-06-01 13:48:03.892426+0800 test[7633:2091245] -[testViewController viewWillAppear:]2017-06-01 13:48:03.899439+0800 test[7633:2091245] -[testViewController viewWillLayoutSubviews]2017-06-01 13:48:03.899963+0800 test[7633:2091245] -[testViewController viewDidLayoutSubviews]2017-06-01 13:48:03.900180+0800 test[7633:2091245] -[testViewController viewWillLayoutSubviews]2017-06-01 13:48:03.900274+0800 test[7633:2091245] -[testViewController viewDidLayoutSubviews]2017-06-01 13:48:04.404022+0800 test[7633:2091245] -[testViewController viewDidAppear:]2017-06-01 13:48:04.404256+0800 test[7633:2091245] -[ViewController viewDidDisappear:]F viewWillDisappearS viewWillAppearS viewDidAppearF viewDidDisappear 执行顺序:loadView(test) -> viewDidLoad(test) -> viewWillDisappear -> viewWillAppear(test) -> viewDidAppear(test) -> viewDidDisappear (4)dismissViewControllerAnimated 123456789102017-06-01 13:52:47.750500+0800 test[7641:2092969] -[testViewController viewWillDisappear:]2017-06-01 13:52:47.750778+0800 test[7641:2092969] -[ViewController viewWillAppear:]2017-06-01 13:52:48.261894+0800 test[7641:2092969] -[ViewController viewDidAppear:]2017-06-01 13:52:48.262125+0800 test[7641:2092969] -[testViewController viewDidDisappear:]2017-06-01 13:52:48.262479+0800 test[7641:2092969] testviewcontroller deallocS viewWillDisappearF viewWillAppearF viewDidAppearS viewDidDisappear 执行顺序:viewWillDisappear(test) -> viewWillAppear -> viewDidAppear -> viewDidDisappear(test) ….testVC Dealloc 模态转场只针对normal情况下,其他模式的转场不太一样,请在实际开发中测试。 (5)TabBar切换 1234S viewWillappear F viewWilldisappearF viewDiddisappear S viewDidappear 执行顺序:viewWillappear -> viewWilldisappear -> viewDiddisappear -> viewDidappear 项目bug在项目中遇见个坑特来记录下: 2017.06.01(暂无解决) 测试环境:xcode Version 8.3.2 (8E2002) 模拟器 iOS 8.4 A push B 描述:A push到 B正常情况下先执行A的viewWillDisappear,后执行B的viewDidLoad,但是在这种情况下出现相反顺序,暂无在真机iOS 8.4上测试。 1234567891011121314151617182017-06-01 15:23:21.236 test[32206:382382] -[testViewController loadView]2017-06-01 15:23:21.236 test[32206:382382] -[testViewController viewDidLoad]2017-06-01 15:23:21.236 test[32206:382382] -[ViewController viewWillDisappear:]2017-06-01 15:23:21.236 test[32206:382382] -[testViewController viewWillAppear:]2017-06-01 15:23:21.238 test[32206:382382] -[testViewController viewWillLayoutSubviews]2017-06-01 15:23:21.238 test[32206:382382] -[testViewController viewDidLayoutSubviews]2017-06-01 15:23:21.238 test[32206:382382] -[ViewController viewWillLayoutSubviews]2017-06-01 15:23:21.238 test[32206:382382] -[ViewController viewDidLayoutSubviews]2017-06-01 15:23:21.238 test[32206:382382] -[testViewController viewWillLayoutSubviews]2017-06-01 15:23:21.239 test[32206:382382] -[testViewController viewDidLayoutSubviews]2017-06-01 15:23:21.763 test[32206:382382] -[ViewController viewDidDisappear:]2017-06-01 15:23:21.764 test[32206:382382] -[testViewController viewDidAppear:]S viewDidLoadF viewWillDisappearS viewWillAppearF viewDidDisappearS viewDidAppear 正常情况下 123456789101112131415162017-06-01 15:24:29.490595+0800 test[7671:2111525] -[ViewController viewWillDisappear:]2017-06-01 15:24:29.491132+0800 test[7671:2111525] -[testViewController loadView]2017-06-01 15:24:29.491375+0800 test[7671:2111525] -[testViewController viewDidLoad]2017-06-01 15:24:29.494997+0800 test[7671:2111525] -[testViewController viewWillAppear:]2017-06-01 15:24:29.521996+0800 test[7671:2111525] -[testViewController viewWillLayoutSubviews]2017-06-01 15:24:29.522274+0800 test[7671:2111525] -[testViewController viewDidLayoutSubviews]2017-06-01 15:24:29.522642+0800 test[7671:2111525] -[testViewController viewWillLayoutSubviews]2017-06-01 15:24:29.522737+0800 test[7671:2111525] -[testViewController viewDidLayoutSubviews]2017-06-01 15:24:30.035553+0800 test[7671:2111525] -[ViewController viewDidDisappear:]2017-06-01 15:24:30.035822+0800 test[7671:2111525] -[testViewController viewDidAppear:]F viewWillDisappearS viewDidLoadS viewWillAppearF viewDidDisappearS viewDidAppear]]></content>
</entry>
<entry>
<title><![CDATA[GitHub使用]]></title>
<url>%2F2017%2F05%2F31%2Fgithub%2F</url>
<content type="text"><![CDATA[Git是一款免费、开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。 Git可以帮助我们管理代码,它是一个分布式版本控制系统。它设计了仓库这样一个管理机制,它不同于SVN集中式的版本控制理念,Git是分布式版本控制。 Git可以通过命令行操作(GitHub客户端有SourceTree,Tower)。 常用的命令行如下 1234567891011121314git init:初始化仓库git status:查看仓库状态git add:向暂存区中添加文件git commit:保存仓库的历史记录git log:查看提交日志git diff:查看更改前后的差别git branch:显示分支一览表git checkout -b:创建并切换分支git checkout:切换分支git merge:合并分支git reset:回溯历史版本git remote add:添加远程仓库git push:推送至远程仓库git clone:获取远程仓库 Git工作流本地仓库是由git维护的三棵“树”组成。第一个是你的 工作目录,它持有实际文件;第二个是 暂存区(Index),它像个缓存区域,临时保存你的改动;最后是 HEAD,它指向你最后一次提交的结果。 第一步:GitHub上创建一个远端仓库 GitHub上注册账号,创建一个远端仓库(复制仓库地址)。 第二步:检出仓库 123456// 克隆到本地cd Documentsgit clone git@github.com:sensencoder/ReactiveCocoaDemo.gitsensencoder表示您的github名字ReactiveCocoaDemo表示您的新建项目名字 第三步:添加gitignore忽略文件 上传项目忽略不必要文件是必须的,Object-C/Swift都有相应的忽略设置,建议在gitignore.io搜索找到相应到的设置,其中有一个比较方便的命令 12gi object-c,macos > gitignorecat .gitignore 然后上传到仓库即可。 123456// 查看仓库状态git status// 添加目录下指定文件git add <filename>// 添加目录下所有文件git add * 1git commit -m "代码提交的说明" 这样您的改动已经提交到Head,但是并没有提交到远端仓库。你的改动现在已经在本地仓库的 HEAD 中了。执行如下命令以将这些改动提交到远端仓库: 1git push origin master 参考链接http://rogerdudler.github.io/git-guide/index.zh.htmlhttps://www.gitignore.io/]]></content>
</entry>
<entry>
<title><![CDATA[ReactiveCocoa]]></title>
<url>%2F2017%2F05%2F25%2FReactiveCocoa%2F</url>
<content type="text"><![CDATA[ReactiveCocoa是在GitHub上开源的一个应用在iOS和OS X的框架,RAC具有函数式编程和响应式编程的一些特性。最近在看有关这方面的知识,先简单说下RAC的简单用法。 安装ReactiveCooa其实安装RAC比较简单,如果通过Cocopods安装的话直接安装2.5.0版本就好(OC)。 12345678<= v2.5:Objective-Cv3.x:Swift 1.2v4.x:Swift 2.xplatform:ios,"8.0"target "ReactiveCocoaDemo" do pod 'ReactiveCocoa', '~> 2.5.0'end ###简单用法 实例:假设在一个登录页面需要输入11位手机号和大于1位的验证码,当满足条件的时候登录按钮可登录。一般平常做法就用TextField代理方法监听即可,但是代码量大一点。 如果采用RAC的话我们可以先创建numberTextField(手机号)和codeTextField(验证码)的信号。我们先通过map方法创建信号。RAC的map方法用于改变信号的返回值,在信号中断后返回bool值。 1234567RACSignal *numberSignal = [self.numberTextField.rac_textSignal map:^id(NSString *username) { NSUInteger length = username.length; if (length == 11) { return @(YES); } return @(NO); }]; 1234567RACSignal *codeSingnal = [self.codeTextField.rac_textSignal map:^id(NSString *code) { NSUInteger length = code.length; if (length > 0) { return @(YES); } return @(NO); }]; 通过创建前面的两个信号判断按钮是否可用,如果前两个信号都为真的话,登陆按钮可用。先看下面的用法 123RAC(self.loginButton,enabled) = [RACSignal combineLatest:@[numberSignal,codeSingnal] reduce:^(NSNumber *isnumberCorrect,NSNumber *iscodeCorrect){ return @(isnumberCorrect.boolValue && iscodeCorrect.boolValue); }]; 总结下:其实就是创建您所需要的信号不用管理他们的实现过程只看结果就行。 RAC本身是一个非常复杂的框架,可以先下载下他的demo,看下源代码。我们可以看出RAC主要由以下四大核心组件构成:1> 信号源:RACStream及其子类;2> 订阅者:RACSubscriber的实现类及其子类;3> 调度器:RACScheduler及其子类;4> 清洁工:RACDisposable及其子类。 从源码中可以知道信号源是最核心的部分,其他组件围绕他运作。信号源码中可以看出,一般分为以下步骤: 1.创建信号2.订阅Next信号3.订阅失败信号4.订阅成功信号 1234567891011121314151617181920RACSignal *testSingnal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@"test"]; [subscriber sendCompleted]; return [RACDisposable disposableWithBlock:^{ }]; }]; // 2.1 订阅Next信号 [testSingnal subscribeNext:^(id x) { }]; // 2.2 订阅失败信号 [testSingnal subscribeError:^(NSError *error) { }]; // 2.3 订阅成功信号 [testSingnal subscribeCompleted:^{ }]; RAC结构挺复杂的最好的建议还是先使用,看源码分析慢慢发掘其中的奥秘。 参考链接[http://blog.leichunfeng.com/blog/2015/12/25/reactivecocoa-v2-dot-5-yuan-ma-jie-xi-zhi-jia-gou-zong-lan/] ()https://github.com/ReactiveCocoa/ReactiveCocoa/blob/v2.5/Documentation/FrameworkOverview.md]]></content>
</entry>
<entry>
<title><![CDATA[iOS分类不能添加属性理解]]></title>
<url>%2F2017%2F02%2F08%2FiOS-category%2F</url>
<content type="text"><![CDATA[在iOS开发中category本来不能为原有类添加属性, 只能添加方法。 下面我们来探讨一下:首先我们创建一个City类,如下: City.h 12345678#import <Foundation/Foundation.h>@interface City : NSObject/// 城市名称@property (nonatomic, copy) NSString *cityName;/// 城市编码@property (nonatomic, copy) NSString *cityCode;- (void)compareCount;@end City.m 123456#import "City.h"@implementation City- (void)compareCount { NSLog(@"%s",__func__);}@end 在所在的控制器里面实现如下方法获取下City类中的属性、成员变量、方法: 1234567891011121314151617181920212223242526272829- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { // 获取成员变量 unsigned int ivarCount = 0; Ivar *ivars = class_copyIvarList([City class], &ivarCount); for (int i = 0; i < ivarCount; i++) { Ivar ivar = ivars[i]; NSLog(@"第%d个成员变量:%s",i,ivar_getName(ivar)); } free(ivars); // 获取属性 unsigned int propertyCount = 0; objc_property_t *propertyList = class_copyPropertyList([City class], &propertyCount); for (int i = 0; i < propertyCount; i++) { objc_property_t property = propertyList[i]; NSLog(@"第%d个属性:%s",i,property_getName(property)); } // 获取方法列表 unsigned int methodCount = 0; Method *methods = class_copyMethodList([City class], &methodCount); for (int i = 0; i < methodCount; i++) { Method method = methods[i]; NSLog(@"第%d个方法:%s",i, sel_getName(method_getName(method))); } } 然后可以获取到编译器控制台打印结果: 1234567891011122017-02-07 17:57:06.969 Test[39527:423417] 第0个成员变量:_cityName2017-02-07 17:57:06.969 Test[39527:423417] 第1个成员变量:_cityCode-------2017-02-07 17:57:06.969 Test[39527:423417] 第0个属性:cityName2017-02-07 17:57:06.970 Test[39527:423417] 第1个属性:cityCode-------2017-02-07 17:57:06.970 Test[39527:423417] 第0个方法:compareCount2017-02-07 17:57:06.970 Test[39527:423417] 第1个方法:cityName2017-02-07 17:57:06.970 Test[39527:423417] 第2个方法:setCityName:2017-02-07 17:57:06.970 Test[39527:423417] 第3个方法:cityCode2017-02-07 17:57:06.971 Test[39527:423417] 第4个方法:setCityCode:2017-02-07 17:57:06.971 Test[39527:423417] 第5个方法:.cxx_destruct 从打印结果可以看出通过@property的时候系统会自动生成带下划线的“_”的成员变量和此变量的setter方法和getter方法,可以这样理解:属性 = 成员变量 + setter方法 + getter方法。那么在分类里面@property是怎么实现的呢,接下来我们创建一个City的分类: City+District.h 1234567#import "City.h"@interface City (District)/// 区@property (nonatomic, copy) NSString *district;@end City+District.m 12345#import "City+District.h"@implementation City (District)@end 这样的话在.m里面会有缺少district 的setter和getter的方法,如果在外部使用的话程序会崩溃 12-[City district]: unrecognized selector sent to instance 0x60000003a800(lldb) 之后写上setter和getter方法之后可以看到打印结果如下 1234567891011121314152017-02-07 18:24:41.435 Test[42031:451930] 第0个成员变量:_cityName2017-02-07 18:24:41.436 Test[42031:451930] 第1个成员变量:_cityCode-------2017-02-07 18:24:41.436 Test[42031:451930] 第0个属性:district2017-02-07 18:24:41.436 Test[42031:451930] 第1个属性:cityName2017-02-07 18:24:41.436 Test[42031:451930] 第2个属性:cityCode-------2017-02-07 18:24:41.437 Test[42031:451930] 第0个方法:district2017-02-07 18:24:41.437 Test[42031:451930] 第1个方法:compareCount2017-02-07 18:24:41.437 Test[42031:451930] 第2个方法:cityName2017-02-07 18:24:41.437 Test[42031:451930] 第3个方法:setCityName:2017-02-07 18:24:41.437 Test[42031:451930] 第4个方法:cityCode2017-02-07 18:24:41.438 Test[42031:451930] 第5个方法:setCityCode:2017-02-07 18:24:41.438 Test[42031:451930] 第6个方法:setDistrict:2017-02-07 18:24:41.438 Test[42031:451930] 第7个方法:.cxx_destruct 可以看出获取到属性列表可以打印出district属性但是并没有district成员变量。也就是说,在setter和getter方法里仍然不能直接访问以下划线开头的成员变量,因为在分类里用@property声明属性时系统并没有添加以“”开头的成员变量。但是可以通过runtime.h运行时来为分类绑定属性,相关代码如下: 1234567891011#import "City+District.h"#import <objc/runtime.h>const void *key = @"key";//制作一个key函数@implementation City (District)- (void)setDistrict:(NSString *)district { objc_setAssociatedObject(self, key, district, OBJC_ASSOCIATION_COPY_NONATOMIC);//为属性绑定set方法}- (NSString *)district { return objc_getAssociatedObject(self, key);//为属性绑定get方法}@end 总结:通过以上的探索可以看出,在分类里使用@property声明属性,只是将该属性添加到该类的属性列表,并声明了setter和getter方法,但是没有生成相应的成员变量,也没有实现setter方法和getter方法,所以说分类是不能添加属性的,但是在分类里使用@property声明属性之后,通过实现setter和getter方法,那么在这个类以外又可以正常通过点语法给该属性赋值和取值。那么在分类里使用@property声明属性,实现了setter和getter方法后,可以认为为这个类添加上了属性。]]></content>
</entry>
<entry>
<title><![CDATA[Hexo Introduce]]></title>
<url>%2F2017%2F01%2F20%2Fhexo_introduce%2F</url>
<content type="text"><![CDATA[Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub. Quick StartCreate a new post1$ hexo new "My New Post" More info: Writing Run server1$ hexo server More info: Server Generate static files1$ hexo generate More info: Generating Deploy to remote sites1$ hexo deploy More info: Deployment]]></content>
</entry>
</search>