您的位置:首页 > 移动开发 > IOS开发

iOS Tips - 02

2015-09-27 11:41 239 查看
1.当一个UI控件 直接 alloc init的时候. 一般是没有大小的(除UIDatePicker UISwitch等除外). 

   但是当 alloc  initWithXXX的时候 有可能跟随着XXX产生了大小.

   比如[[UIImageView alloc] initWithImage:..] 跟随者image产生了大小.

2.利用xcode自带的拉伸功能 能把图片拉伸.

注意: 如果想拉伸的方向 图片在这个方向上不规则,比如有突起,那么这个方向就不能拉伸

3.一个应用程序 只有一个keyWindow. 但是可以有很多window.越后面显示的window 越在上面.

4.KVC  (可设值 也可取值)

1.利用KVC 可以随意修改 readOnly的属性 (私有的也可以!)

2. 若属性为 @property (..,..) NSString *name ;  key 为 @"name" 或者 @"_name"都可以. 

3.forKey 和 forKeyPath的区别

如果key为  @"dog.name"

对于forKey来说, key就是属性 "dog.name" 不会分开.

对于forKeyPath来说.  key是 属性dog 里面的属性name .等于说 能深入属性进去找.

4.当发现 key的其中一个字段是数组 @"books"

若后面什么都没有了,那么和之前一样 直接返回一个数组.

若后面还有,比如NSArray *names =  [p valueForKeyPath:@"books.name"]; 那么会取出该数组中的每一个元素的name属性值,放到一个新的数组中返回!

5.还能对取出的数组进行一些计算 比如计算总和.  [p valueForKeyPath:@"books.@sum.price"]; 注意:KVC一般返回的是对象, 总和若为 数字 则需要手动转化一下.

5.添加了子view后 当父view的大小发生改变 会改变子view的大小! 也就是说就算设置了子view的大小,然后将它添加到父view上,但是之后父view的大小发生变化 子view的大小会随着父view大小的变化而变化.(所以此时子view并不是预期的大小)

所以要在父view大小变化完后 再将子view添加到父view 这样比较好

6.UIScrollView 若想让某个方向不能滑动,那么设置contentSize width/height 为0即可
7.一个子控件超出了父控件的范围 也能显示 但是根据事件传递机制 是无法触摸的.
8.一个浮点数 想要四舍五入后变成整数 该怎么办?
     默认情况下变成整数时,会直接丢弃小数点后面的数字.
     这时候 我们只需要在变成整数前先给浮点数加0.5
这样就能达到四舍五入的效果!
9.如果控制器的view还在,但是view上面的数据不显示,很有可能控制器已经被销毁了.
10.如果一个view要添加另外一个view. 而且调用了无数次 ,其实只会添加一次
11.一个控制器 点击了按钮后添加其他控制器.如果添加多个控制器. 这个时候 可以保存这几个控制器的引用.只需切换的时候控制器的view removeFromSuperview即可.不需要为了节约内存舍弃控制器的引用.
     问题来了,怎么保存引用?
           1.直接添加属性引用,这样没有扩展性.麻烦.
           2.每个控制器都有childViewControllers数组,放在这数组里面就好了! 
当控制器的view为父子关系时,那么控制器最好也为父子关系.
12.在scrollview里面 不要随意的使用 [scrollView.subviews lastObject] 获取自己添加的最后一个子控件.因为UIScrollView可能会自己在里面添加一些控件 这个时候lastObject获得的不一定是自己的子控件

13.UIImageView加载本地图片有2种:
     1.imageWithContentOfFile:
这个方法加载的不会有缓存.适合用来加载大图片
           注意:
在iOS7中放在images.xcassets的图片 在编译之后 会打包成 Assets.car. 这时候NSBundle mainBundle无法找到打包成Assets.car的图片.在iOS6的时候 没这么先进,不会打包,所以mainBundle能够找到
           总结:大图片不能放在images.xcassets 里面.

     2.imageNamed:
这个方法加载的会有缓存,适合用来加载小图片 (这个缓存是系统管理的,无法干预)

14.block的细节和本质

1.block中引用的局部变量:

1.普通的局部变量,block内部只会引用它初始的值(block定义那一刻),不能跟踪它的改变,比如
int age = 10; 那么块代码里面保存的 其实就是10,不管后面age会怎么改变(本质 值传递)

2.被__block修饰的局部变量.那么就不一样了! 
block内部能够一直引用被__block 修饰的局部变量!(本质:地址传递)

3.被static引用的局部变量. 与2的情况相同(本质:地址传递)

为什么会这样?
因为block不知道普通的局部变量什么时候会被销毁 只能在block定义的时候 直接拿过来,而statc引用的局部变量, 运行过程中永远都会存储在内存中,所以不用急急忙忙地直接拿过来 用到的时候获取值就可以了.__block修饰有能保住局部变量不被销毁的功能

2.block中引用的全局变量:(本质:地址传递)

根据1中总结的 毫无疑问 block能一直引用.

3.最后举个栗子:

int a = [self XXXXXwithHandler:^{

NSLog(@"%d", a);

}];

执行顺序:

1.先定义 int a;

2.调用方法 (在这时block定义了)

3.调用完方法 返回值给a.

结果: 以后不管什么时候调用block,打印的值永远只能是0.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  iOS 学习笔记