零散学的逐渐积累的知识点

零散学的逐渐积累的知识点

block 循环引用

因为在设置block 属性的时候设置的是 copy, 这就会使得传入的 block 都是 copy 到这个属性, 而 block 属性又归 self 所有, 最终在 block 里使用 self 的时候会强引用 self, 这就形成了循环引用, 设都释放不了.
解决>>>>> 在 block 引用 self 之间做一个中介, 中介弱引用 self, 但是还是指向 self, 操作同一个内存.
    __unsafe_unretain 类名 *变量 = self.  就做了一个弱引用 self 的变量. 在 block 中用这个变量, 就不会强引用 self 了,
    __weak 异曲同工, 只是 weak 会在内存释放时自动给变量设置 nil, 而__unsafe 不会, 所以 weak 更安全, 不会有野指针的问题
    注意: _age 这种方式访问属性相当于 self -> _age, 也会强引用 self
 block 默认创建的时候是爱栈内存中, 当被 copy 引用后被赋值到堆内存进行强引用

autoResizing

在设置 View 的时候, 尺寸那一栏的设置里有个伸缩图, 里面的箭头的意思可以简单的看图猜到, 上下左右的线代表控件距离父控件上下左右的距离变不变, 里面的是宽高要不要随着父控件的改变而等比例改变. 可以设置几个 View 实验一下
用代码实现的话就是 view.autoResizing 属性的设置, 有几个值, 对应 图里的几个线, 注意: 代码中设置的是可拉伸. 和图里的是相反的
以后(现在)大力使用 autoLayout, 这个只需要简单了解即可

试了之后: 四顶角: 有 autoLayout 的话会保留上面的, 没有的话就是取中间, 上下两头会截断
中间的2个箭头: 是否随父控件拉伸改变
四周 : 是否和父控件的四边保持距离

strong - weak

控件和代理应该用 weak
    只要没有强指针引用内存对象, 对象就会被释放
    所以: *循环引用会造成内存对象都不释放, 但是又没有变量指向他们了, 最终会造成内存泄露*

    控件: 控件添加给父控件后, 父控件中有一个 subViews 属性保存这些子控件, 是个数组, 数组里的每个元素都指向对应的子控件存储空间, addto 也是个强引用, 这里如果直接想通过一个属性来操作子控件, 设置 strong 和 weak 是一样的, 因为父控件一旦被释放, 顺下去都没有强引用了, 也就没有任何强引用子控件, 子控件也会被释放, 但是一个循环不应该被闭死, 所以直接操作子控件的自定义属性应该设置 weak

    代理: 一个控制器中有 view, 有些 View 里面有代理属性, 而 View 的代理一般是自己的控制器. 控制器对 View 是强引用的, 此时如果代理对控制器强引用的话, 就会循环引用了, 如: UITableViewController.tableView.delegate

技巧: 保存自己设计的类是, 把不一样的需要特殊这只的用<#name#> 起来

提取代码

如果一个程序写的是比较正规的, 耦合性不强, 可以将其某些功能提取出来, 单是耦合性很强的话, 几乎整个项目都拿过来了, 等于没提取
通过先跑起来看看想要的功能模块在那个控制器, 然后找里面的代码, 相关的联系, 然后找到对应的类后通过注释代码, 看看是怎么做的, 理解作者程序, 理解模块运行

log 日志增强

在数组和字典中打印对象不能很好的支持中文, 需要写个分类来重写 description 方法, 在里面将要打印的内容拼接起来, 可以在 Foundation 的分类中写, 这样在程序一运行加载框架时就会加载这些分类了

项目

在打开不同 Xcode 版本创建的项目时, 可能会有一些混乱, 这时候打开项目中.xcode 文件包内容, 删除 xcuserdata文件夹就好

看下å其他项目的操作, 实现了什么功能和效果, 看能不能实现这些效果

刚进去时有需求的时候, 要怎么整理, 规划, 从哪里下手

规范是项目组的话, 有移动开发组(Android/iOS), 服务器组. 一般有接口文档的话不需要过多的交流, 规范化开发可以减少沟通成本, 产品需求组(确定需要什么功能, 什么特色, 产品经理)
    接口文档:
        * 说明接口作用
        * 接口的 URL
        * 请求方式
        * 需要传递的参数,
        * 返回的类型, 内容, 格式.etc
        * 会返回怎样的数据类型, 返回的字段, 键值对应是什么意思

项目组:
    * 移动开发组       开发客户端
    * 服务器开发组        提供接口
    * 产品需求组       设置需求
    * 测试组         测试 bug
    * 美工组         界面, 一般也是产品经理
项目文档
    * 需求文档      需求组
    * 接口文档      服务器组
    * 产品文档      对外界介绍产品的价值, 优势.etc  对拉投资有用
    * 开发文档      开发时的注意

项目架构    看公司的规模
    * UI 界面层
    * 业务类层
    * 网络处理层
    * 工具类层
分工
    * 按功能和模块分
    * 按项目层级分

项目搭建

* 一般, 按照规范的话是先有人打一个框架, 然后将不同的功能模块分配给其他人做, 或者按层级划分, 独立的话, 还是自己来把, 先搭个框架, 按模块一个个做,
* storyBoad 在很多老项目中没有, 而且有些情况下也不好试, 微博项目用代码搭建, 在项目的 Target 中把 MainInterface 清空, 不然系统找不到会报错
* 纯代码的话, 要从 application.m 开始, 自己创建 window, 然后将根控制器放上去
* 项目的图片有时候没有对应的图片显示的话,

集成下拉刷新

iOS 的 UIKit 中已经自带有一个刷新控件: UIRefreshControl, 里面有使用说明
刷新的时候调用微博 API 获取最新的数据, 如果直接调用homeLine 方法的话, 会请求最新的 n 条数据直接覆盖原来的模型, 就会有些数据重复加载, 理想状态应该是加载我没有的新的数据, 并把数据放在最上面
每个微博都有个 id, id 自增, 所以最新的微博 id 最大, 且在最上面, 我们应该调用 since_id 这个接口, 获取我们最大 id 后面的微博
    发送请求获取新的 id, (当本地模型有值时才赋值 since_id), 将最新的模型数组 insert 到原来数组的最前面, NSIndexSet *, 确定范围
    刷新 tableView, 刷新后调用 refreshCOtrol 的 endRefresh 回复到默认状态

截图实现一些效果

用qurze2d来将view.layer render到bitmap上下文, 获得uiimage后再截取一部分成cgimage, 截取范围可以拿到cell在view中的位置, 分割后在y值处添加一个collectionVIew, 需要判断collectionView在不在可视范围, 需要保证在可视范围, 再把图片盖上去, 然后再用动画效果将下截图片往下移, 上截图片往上移至collectionView的上下两端

升级 xcode7.2后问题: 程序运行上下有黑边:选中target——>general——>app icons and launch images——>Launch Screen File——>选择一个 storyboard file文件,编译运行即可,打包后,黑边问题不再出现!或者选一个 launchimage 到对应的地方

做项目遇到的问题:

*  在点击评论或者什么, 有时候需要登录才能评论的, 先 modal 登录控制器, 成功后应该在后面想之前的控制器发送消息, 让之前的控制器偷偷的五动画 push 一个评论控制器, 再把登录控制器 dismiss, 这样就能 dismiss 后就可以输入评论, 如果登录了就直接 push 评论控制器
*  在导航栏下面有选择条可以点击切换不同控制器时, 其实是想 tabbar 一样点击时把控制器.view 添加到主页显示出来, 可以滚动, 说明几个控制器.view是连在一起放到 scrollView 或者collectionView 上的, 点击不同的滚动条标签就切换到对应的 view

#整理接口文档: 未做

* 在抓数据过程中, 最好整一份接口文档, 因为抓下来的数据比较乱, 整理好了方便以后查看
* 收先格式化数据(json 格式化)
* 打开格式好的html, firebug 查看对应的元素来修改,改好后用全赋值粘贴到文件中, 之后返回的数据的用 ultroEdit 将格式化好的东西, 替换到 pre 标签中, pre 标签会保持其中的格式

#从 IOS6开始, 对于应用会涉及到用户隐私的操作, 苹果都会弹框提示用户是否允许

#关于私有API

* 存在, 但是敲没有提示的类, 敲不出来, 提示报错的, 就是私有, 不然敲的出来的都不是私有的
* 但是可以通过转换类来使用, 但是使用了私有的, 可能就上不了架, 不建议这么使用  :  Class c = NSClassFromString();
*

##注意: 凡是看到copy / new / create / retain / 的东西, 又没有专程O OC 来进行 ARC 管理的, 都要在用完后 release, 用: CFRelease(xxx)

#ARC 和MRC 混合开发,

* 文件比较少, 又想看源代码的时候, 可以在 buildsetting 里一个个文件设置其为-fno-objc, 但是文件多的话就惨了, 用 ARC转换的话又有些会报错的可能, 如果只是用, 不想改动源代码, 或者已经调试好源代码的情况下, 可以将这个框架打包成一个静态库或框架, 我们拿到头文件和静态库就可以了, 不用每个文件的标志了
* 还有方法比较复杂, 像 vlc 的那样, 在一个项目里引用另外一个项目,但是这个方法要配置很多东西, 比较复杂
* 或者有提供 pod 的直接 install 就可以安装依赖,

##日期判断:

* 使用 NSDateFormatter转换字符串和 date 之间, 需要定义时间的格式
* 使用 NSCalender 可以判断2个日期之间的间隔
*

##模型的重要,

* 根据 MVC 的模式, 视图的展示都是由模型提供数据的, 如果要修改上面的数据, 就去修改模型, 在刷新视图
*

##抽取父类,

* 相同类似的东西, 模型, 控件, 控制器等, 都可以抽取到父类中, 由父类完成相同的操作 再提供接口给子类实现差异化
*

关于 css/xpath 选择器

http://www.cnblogs.com/ziyunfei/archive/2012/10/05/2710631.html

技巧:

####全局断点: 在导航区ccommand+6, 下面选择Add Exception BreakPoint: 异常断点, 会在报错的那行代码停下

封装 UIView 分类, 方便设置 frame 或者其他结构体的属性, 因为这个很常用, 现在有些框架也自己封装了这些边界操作, 像 MJExtention, Gallop 等

挖掘子控件,

有时候为了调试, 我们可以将整个 window 的 subVIew 打印出来, 看下层级关系, 在遍历的时候将子控件的关键信息拼接成字符串给 xml, 在浏览器中打开就可以清楚的看到层级关系

截图实现一些效果

用qurze2d来将view.layer render到bitmap上下文, 获得uiimage后再截取一部分成cgimage, 截取范围可以拿到cell在view中的位置, 分割后在y值处添加一个collectionVIew, 需要判断collectionView在不在可视范围, 需要保证在可视范围, 再把图片盖上去, 然后再用动画效果将下截图片往下移, 上截图片往上移至collectionView的上下两端

#关于私有API

* 存在, 但是敲没有提示的类, 敲不出来, 提示报错的, 就是私有, 不然敲的出来的都不是私有的
* 但是可以通过转换类来使用, 但是使用了私有的, 可能就上不了架, 不建议这么使用  :  Class c = NSClassFromString();

#iOS版本判断:
[[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){9,3,0}];

#warning: KVC 可以通过 key 访问任何属性和成员变量)

* 可以使用 indexOfGroup....来返回一个数组, 这个数组作为整个 table 的组的索引, 它是按照索引来对应组的, 所以索引的顺序应该和 table 数据源提供的组的数据一致
* 可以用 KVC 来获得一个数组里其元素的某个属性的值, 数组里有多个属性有这个值, 所以最后返回的是每个元素的这个属性值的数组
* 也可以调用其属性设计组 indexColor
* 查看重叠的所有 UI 控件: Shift+Control+单击
*

##可以使用判定: NSPredicate 来设定判定条件, 用数组来调用根据判定来过滤出符合的数组来返回: filteredArrayUsingPredicate:, 在判定中, 是用字符串来描述的, 其中 数组中元素属性名 contains 匹配字符串, 其中元素属性可以跟上 OC 的语法, 不过也是在字符串中的, 类似就是调用了 KVC 的方法, i.e. : name.lowercaseString, 一样可以将 name 的字符串转成小写, 也有点想数据库的写法

#bug: CUICatalog: Invalid asset supplied: (null), or invalid scale factor:1.000..
———– 当设置图片传空壶有这个警告或者传入的图片找不到

#bug: 当点击菜单按钮时, 崩溃, reason: ‘-[UITableView _contentOffsetForScrollingToRowAtIndexPath:atScrollPosition:]: row (2) beyond bounds (0) for section (0).’ —–
——-点击菜单后, 里面有对 tableView selectRow 的操作, 滚动到某一行, 但是这行不存在, 因为这个 tableView 的数据没有, 所以在初始化的时候必须要有数据, 才能这样操作

#安装 cacoaPods 的坑,

  • Error installing cocoapods:
    activesupport requires Ruby version >= 2.2.2.
  • 你的 Ruby 环境版本必须大于等于2.2.2.于是,我输入了 gem –version.结果出来的版本号是2.6.0.我说这明明大于2.2.2.怎么还提示版本太低呢.结果一查才知道:rvm是用来管理ruby的,ruby的其中一个“程序”叫rubygems,简称 gem,而用来管理项目 的gem的,叫bundle.完全是不同的东西,他们相同的只是都可以管理gem.所以说不能用这个.得用rvm list.一查, ruby 的版本好像是1.9.8吧,看来是cocoapods 没骗我.接下来的工作就是升级 cocoapods 了.
  • http://www.it610.com/article/2113275.htm
  • 需要更新 HomeBrew
  • 更新 rvm, homebrew 后, 重新安装, 完成
  • http://www.cnblogs.com/yan520/p/5583362.html, 像这个里的问题又有了…..
  • http://www.jianshu.com/p/6e5c0f78200a/comments/2274069
    *

#bug: linker command failed with exit code 1 (use -v to see invocation)
之前项目里有文件和 pod install里的库是一样的, 删掉就好

#bug: 用 UITextVIew 做富文本连接点击识别时, 获取链接的范围总是几乎{1, 0}之类的,
— 需要将 textView 加到一个 view 中作为子控件, textView 自己不能交互, 用父控件的触摸事件来定位点击rect 和点

#bug: 将做好的显示属性文本的控件加到一个 view(containView) 上时, 虽然 view 可以根据里面 textView 的变化改变 size, 但是在更外满一层使用这个控件的 view, 不能根据containView 的 size 改变而改变, 只能拿到这个 containview 的高, 加上其自己本来能自动布局的高,

#注意: 在自定义控件的时候, 最好 initWithFrame 和 initWithCoder 一起实现, 将初始化代码放在 setup 类似的方法里在上面两个方法中调用, 免得在 xib 使用时没有调用其初始化方法,

#bug: systemLayoutSizeFittingSize:UILayoutFittingCompressedSize的坑:

* 在使用这个方法时, 只能自适应其中固定了尺寸宽高的控件, 像自己做的这个显示富文本的控件, 放在一耳光 view 里了, 默认 view 没有自动适应内容高度, 所以外面在fit 的时候, 就不会将这个 view 考虑在内, 或者考虑为0, 所以需要自己拿到改变的高自己计算高度,

#注意: sizeThatFits的坑: 这个如果宽度不够, 一样只会取最少的返回, 所以要固定宽的话, 也要另外设置

#bug: SQL 数据库要搜索的字段是TEXT的话, 执行语句里要加上’’,

#bug: [_NSInlineData firstObject]: unrecognized selector sent to instance 0x7bae9200
AFN 按理说返回的是 json并自动会转成字典或数组, 但是有时候会成这个会成这个类….奇怪
可能是发送请求的时候共用了一个 manager, 在这个发送请求未返回时, 其他的操作又设定了这个的 responseSeriarazer 设定为其他的了

#bug: 登录操作 POST 参数到对应地址后返回的是相当于加载主页的内容

#注意: 由于Stack View自动为我们管理Auto Layout constraints,我们只能调用layoutIfNeeded来实现动画。

#问题: scrollView 在使用自动布局时, 设置了上下左右后还是会提示有错, 有约束没有设置, 而且运行后有时滚动不了,
先猜想: 其布局和普通控件不一样, 果然, 它除了 pin 在四周的设置外, 还会根据子控件来设置其 contentSize, 没有足够的约束来计算的话就会报错, 可以在 scrollView 里设置一个 contentView 来填充其内部, 所有要在滚动视图的子控件都加在 contentView 中, 而且子控件要连贯其上下或者左右来设置约束, 这样这个 contetntView 就会根据内部的子控件来计算 size, scrollView 是根据这个 contentView 来算 contentSize, 如果不想哪个方向滚动, 可以设置 contentView 的高/宽 = scrollView.高/宽, 相当于 contentSize 的高.宽被设定死了, 在高/宽方向不滚动
Google 后发现其底部和右边的约束是对其 contentSize 的设置, 即约束里的 width 和 height 是对其滚动范围的设置
https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithScrollViews.html

#bug: 代码设置 contentOffset = xx, 无效, setContentOffset:animated:方法无效
cao !!其实是有效果的1!!! 在更换了 xib 文件中的控件时忘了重新联建 scrollVIew! 到时其 = nil;
在网上找到些这些问题的方法, 记录下, 以后要是真碰到了无效的话试试.

1. 强制回主线程操作:
dispatch_async(dispatch_get_main_queue(), ^{
     这里设置 offset
});
  1. pagingEnable = no;, 设置完 offset 再设置回来
  2. delegate = no; 设置完 offset 再设置回来

#bug: 这是在搜上面的问题时顺便搜到的, 以后可能有用, 问题是当 pop 会 scrollview 时, 里面的控件和 tabbar 会有奇怪的布局现象, 解决方法:
In iOS 7/8/9 simple self.automaticallyAdjustsScrollViewInsets = NO; solved the problem in my case.
原文连接: http://stackoverflow.com/questions/17404682/uiscrollviews-origin-changes-after-popping-back-to-the-uiviewcontroller

关于 css/xpath 选择器

http://www.cnblogs.com/ziyunfei/archive/2012/10/05/2710631.html

#bug: library not found for -l AFNetworking

1. 在使用了 pod 后打开的是 xcproject, 而不是 xcworkspace, 因为这些路径自动加入是 workspace 的事,
2. 在没有使用 pod 的时候, 检查在那个Library Search Paths需要有这个库的路径
3. 没有使用 pod 的话, 也要看这里有没有包含有这个库的路径, 不然会报找不到的错误

#bug&warning: 关于 textView 内容更新及其尺寸的更新
在内容更新后, 会自动更新内容, 但是设置的大小, 要先[self.attView sizeToFit], 或 sizeThatFit:方法重新计算, 其容器才能根据这个 textView自动计算出来的尺寸设置其他东西, 而且要在外层

关于 View 布局的注意, 当 view

// [la setNeedsLayout]; // 可以, 这个方法会调用其中的 updateConstrains 和 layoutSubviews 方法
// [la setNeedsDisplay]; // 不行, 只会调用updateConstraints
// [la setNeedsUpdateConstraints]; // 不行, 只会调用updateConstraints
[self invalidateIntrinsicContentSize] // 当改变了内部内容的尺寸时, 要调用这个

##所以, 当想要都调用 View 中两个方法的话, 只能使用setNeedsLayout

#textView 布局注意

- 在设置好宽度后, 直接 sizeToFit 就可以或者 sizeThatFit:, 但是在 view 中直接用textVIew的话好像不行, 要自定义一个 tetxView, 在 layoutSubView 中实现重新设置 size 才可以...
- 目前在 textView 的属性文本中添加的图片如果修改了尺寸的话, 好像它还是按照原来的尺寸来适应这个高度, 还要设置 attach.bounds 才能按照这个 bounds 来布局

#bug: 在编译RegexKitLite的时候,报错如下:
Undefined symbols for architecture i386:
“_uregex_open”, referenced from:
_rkl_getCachedRegex in RegexKitLite.o

– 解决办法:
在项目的编译设置中找到Other Linker Flags,然后在后面字段空白处双击,添加“-licucore”就可以了。

#bug: 在用 analysis 时候(不小心点中的)发现在 AFN 里使用 rechability 的时候有内存泄露,
搜到的方法: https://github.com/tonymillion/Reachability/issues/114

#bug: 换了 TYAttributed 后, 在显示 headerView 正常, 但是显示cell 的时候会不显示文字, 且cell 的计算高度会递增
目前根据一些测试猜测: 计算高度的时候用的是同一个 cell, 里面的控件可能对高度进行了缓存, 导致没次算的时候都会有上面一些的影响
进一步发现, 还是自己的代码写的不够严谨, 在封装好的 Label 中, 对内部 TYAttributed 的使用是 append 富文本, 如果一致使用同一个, 就会一直拼接上去, 最后 attributedString 会越来越长, 造成计算的高度越来越大.
注意自定义控件的时候会有复用的可能

#bug: 单独抽出这个 cell 及 YCAttributedLabel 来测试时, 产生一样不识别, 且都挤在第一行上.

#bug: 想在异步线程完成用自适应的方法计算出高度时,
2016-10-18 17:20:33.133 tableViewtest[40456:2268670] This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes. This will cause an exception in a future release.

不然异步线程进行自动布局的相关操作

#bug: [NSError init] called; this results in an invalid NSError instance. It will raise an exception in a future release. Please call errorWithDomain:code:userInfo: or initWithDomain:code:userInfo:. This message shown only once.
看来直接 init 的 NSError 不好哦, 以后可能会出问题