1.iOS中delegate代理对象使用weak

   之前不停的使用assign,今天在调试一段的时候,发现使用assgin的时候程序会crash,报错EXC_BAD_ACCESS, 经过一番研讨,发明如果应用 @property (nonatomic, assign, readwrite) id delegate;,用assign声明一个delegate,那么即便代理指向的对象销毁了,delegate中依然会保持之前对象的地址,即代理成为一个野指针,所以导致程序会crash,而用weak修饰,则不会有上诉的问题,当代理指向的对象销毁后,delegate = nil, 所以为了以后出现问题,最好delegate最好用weak修饰。

  下面两种方式都是弱引用代理对象,但是第一种在代理对象被释放后不会导致崩溃,而第二种会导致崩溃。

  @property (nonatomic, weak) iddelegate;

  @property (nonatomic, assign) iddelegate;

  weak和assign是一种“非拥有关系”的指针,通过这两种修饰的指针变量,都不会改变被引用对象的引用计数,但是一个对象被释放后,weak声明的会自动将指针指向nil,而assign则不会,在iOS中向nil对象发送消息时,不会导致奔溃,所以assign就会导致野指针的错误unrecognized selector sent to instance。

  总结:如果我们修饰代理属性,最好还是用weak修饰吧,比较安全;

2.nonatomic,assign,copy,retain的区别

nonatomic:非原子性访问,不加同步,多线程并发访问会提高性能。如果不加此属性,则默认是两个访问方法都为原子型事务访问。

(atomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所 以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。)

assign: 简单赋值,不更改索引计数
               对基础数据类型 (NSInteger)和C数据类型(int, float, double, char, 等)

copy:建立一个索引计数为1的对象,然后释放旧对象  
            对NSString

retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1
             对其他NSObject和其子类

  copy与retain的区别:
  copy是创建一个新对象,retain是创建一个指针,引用对象计数加1。
eg:   一个NSString 对象,地址为0×1111 ,内容为@”STR”

  在MRC环境下使用retain修饰对象类型,使用assign实现基本类型.

在ARC环境下,看资料说,strong相当于retain,weak相当于assign,但是我发现,weak只能修饰对象类型,而assign使用于修饰基本类型的

Copy 到另外一个NSString 之后,地址为0×2222 ,内容相同,新的对象retain为1 ,旧有对象没有变化

retain 到另外一个NSString 之后,地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1

也就是说,retain 是指针拷贝,copy 是内容拷贝。

3.定时器,在scrollerView滚动的时候,定时器NSTimer会暂停回调,为什么,如何解决? 

    RunLoop只能运行在一种mode下,如果要换mode,当前的RunLoop对象也会停止下来,重新开启新的RunLoop对象,利用这个机制,ScrollView在滚动过程中NSDefaultRunLoopMode(kCFRunLoopDefaultMode)的mode会切换到UITrackingRunLoopMode来保证ScrollView的流畅滑动:如果只在NSDefaultRunLoopMode模式下处理的事件会影响ScrollView的滑动,如果我们把一个NSTimer对象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主运行循环中的时候, ScrollView滚动过程中会因为mode的切换,而导致NSTimer将不再被调度。

    解决方案:Timer计时会被scrollView的滑动影响的问题可以通过将timer添加到NSRunLoopCommonModes(kCFRunLoopCommonModes)来解决。代码如下:

//将timer添加到NSDefaultRunLoopMode中
 //然后再添加到NSRunLoopCommonModes里 
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerTick:)userInfo:nil repeats:YES]; 
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
 

最新文章

  1. linux Mysql 安装及配置
  2. 关于对For循环嵌套优化的问题
  3. HttpResponse的使用方法
  4. ASP.NET中进行消息处理(MSMQ) 二(转)
  5. POJ2406----Power Strings解题报告
  6. Oracle 常用命令大全
  7. Long Long Message
  8. MVC6项目
  9. .NET重构—单元测试重构
  10. 【strtok()】——分割字符串
  11. 201521123025<<java程序设计>>第9周学习总结
  12. MYSQL导入大量数据碰到的问题及解决方法
  13. OpenCV+python 人脸识别
  14. Linux常用命令(第二版) --Shell应用技巧
  15. [BZOJ 4818] [SDOI 2017] 序列计数
  16. 使用Laya引擎开发微信小游戏(下)
  17. MYSQL数据库安装记
  18. Hibernate表关系03
  19. 【codevs4919】线段树练习4
  20. 放弃 Tightvnc, 选择 Tigervnc

热门文章

  1. Visual Studio 2012的开发使用技巧
  2. WCFRESTFul服务搭建及实现增删改查
  3. 前端MVVM框架avalon - 模型转换1
  4. [转载]expect spawn、linux expect 用法小记
  5. 4605 Magic Ball Game
  6. 调试设置移动端Web开发环境搭建实践
  7. C#基础知识——类的继承
  8. Testlink1.9.14介绍及使用
  9. Linux之初体验
  10. 【CSS学习笔记】背景图片