programming with oc回顾笔记
2015-09-11 17:15
246 查看
对于readwrite property, 如果getter setter都被重写了,则编译器不会自动生成 instance variable,得自己定义。对于readonly,getter被重写了也是同理。
正确的使用weak。
为了避免循环引用,会使用weak,但是weak的对象随时可能不在,那么如何处理呢。
如果是对weak发消息,那么什么也不会发生,没问题
如果讲weak对象作为参数传入,则要看该方法是否支持传入nil。例如 dictionary setObject就会出现异常导致崩溃。
如果一定要确保weak对象是存在的。那么就需要先用一个本地变量来强引用这个weak变量,官方的例子:
在强引用之后,先判断对象是否存在,如果存在,那么之后使用这个对象一定是存在的。用完之后再nil,其实最后一步是不需要的,因为是方法体内的本地变量,作用域消失之后会自动nil。这种写法特别适合网络请求异步回调的block代码。
property如果是copy属性的,如果在初始化方法中赋值了对应的instance variable,则一定要使用copy方法。
id<delegate>作为property,官方建议使用weak属性来避免循环引用。同理,在具体使用的时候,如果一定需要确保delegate存在,同样使用本地变量强引用之后再用。
代理的可选方法,定义者在向代理发消息之前要先检查是否代理实现了该方法。
之前接手一个项目,就遇到声明是optional,实际上却不做检查,我实现了代理的required部分,结果optional方法被强制调用,导致崩溃。
fast enumeration with collection
enumeration的过程中,不可以修改collection,runtime会抛异常的。
block
如果定义了一个block变量,调用的时候如果变量是nil,会crash。到目前学习实践的项目暂时为用到将block作为property来传递的,觉得这样乖乖的。作为方法的参数感觉比较顺,在方法里面调用前先判断一下,如果block不是nil再调用。
如果作为property,官方建议添加copy属性,官方说ARC会自动做copy,为了看起来更清楚建议还是这样写。
block循环引用的问题
因为我们在block中大多数都会用到self,所以容易产生循环引用
如果block作为self的property,则铁定循环引用
如果block作为参数传递,例如网络异步请求的回调block,大多数self都是UIViewController,用block更新UI的,这个时候会产生一个现象,也就是由于block强引用了UIViewController,所以在网络请求没有结束之前,即使用户点了返回按钮,UIView在界面上不存在了,但是也不能被释放掉。所以也不能使用self.
针对不同类型变量:
scalar variable:int ,float etc block是值COPY
Object-C object variable:
如果是local variable: 指针的值COPY,不会强引用self
如果是instance variable: 强引用self
如果是self.property,强引用self
Name Convention
对于bool property,如果要兼容kvc,那么getter方法要修改为isXXX,除了bool property,其他类型的完全没有必要另外定义名字。
正确的使用weak。
为了避免循环引用,会使用weak,但是weak的对象随时可能不在,那么如何处理呢。
如果是对weak发消息,那么什么也不会发生,没问题
如果讲weak对象作为参数传入,则要看该方法是否支持传入nil。例如 dictionary setObject就会出现异常导致崩溃。
如果一定要确保weak对象是存在的。那么就需要先用一个本地变量来强引用这个weak变量,官方的例子:
NSObject *cachedObject = self.someWeakProperty; // 1 if (cachedObject) { // 2 [someObject doSomethingImportantWith:cachedObject]; // 3 } // 4 cachedObject = nil;
在强引用之后,先判断对象是否存在,如果存在,那么之后使用这个对象一定是存在的。用完之后再nil,其实最后一步是不需要的,因为是方法体内的本地变量,作用域消失之后会自动nil。这种写法特别适合网络请求异步回调的block代码。
property如果是copy属性的,如果在初始化方法中赋值了对应的instance variable,则一定要使用copy方法。
- (id)initWithSomeOriginalString:(NSString *)aString { self = [super init]; if (self) { _instanceVariableForCopyProperty = [aString copy]; } return self; }
id<delegate>作为property,官方建议使用weak属性来避免循环引用。同理,在具体使用的时候,如果一定需要确保delegate存在,同样使用本地变量强引用之后再用。
代理的可选方法,定义者在向代理发消息之前要先检查是否代理实现了该方法。
之前接手一个项目,就遇到声明是optional,实际上却不做检查,我实现了代理的required部分,结果optional方法被强制调用,导致崩溃。
NSString *thisSegmentTitle; if ([self.dataSource respondsToSelector:@selector(titleForSegmentAtIndex:)]) { thisSegmentTitle = [self.dataSource titleForSegmentAtIndex:index]; }
fast enumeration with collection
enumeration的过程中,不可以修改collection,runtime会抛异常的。
for (id eachObject in array) { NSLog(@"Object: %@", eachObject); }
for (NSString *eachKey in dictionary) { id object = dictionary[eachKey]; NSLog(@"Object: %@ for key: %@", object, eachKey); }
block
如果定义了一个block变量,调用的时候如果变量是nil,会crash。到目前学习实践的项目暂时为用到将block作为property来传递的,觉得这样乖乖的。作为方法的参数感觉比较顺,在方法里面调用前先判断一下,如果block不是nil再调用。
如果作为property,官方建议添加copy属性,官方说ARC会自动做copy,为了看起来更清楚建议还是这样写。
block循环引用的问题
因为我们在block中大多数都会用到self,所以容易产生循环引用
如果block作为self的property,则铁定循环引用
如果block作为参数传递,例如网络异步请求的回调block,大多数self都是UIViewController,用block更新UI的,这个时候会产生一个现象,也就是由于block强引用了UIViewController,所以在网络请求没有结束之前,即使用户点了返回按钮,UIView在界面上不存在了,但是也不能被释放掉。所以也不能使用self.
__weak UIViewController * ws = self; [function call: ....... completion: ^{ //如果后续逻辑不一定要求对象一定存在,则不需要这一步,大多数情况是不需要的。 __strong UIViewController sws = ws; if (sws) { //如果一定要对象存在才能执行的逻辑 } }];
针对不同类型变量:
scalar variable:int ,float etc block是值COPY
Object-C object variable:
如果是local variable: 指针的值COPY,不会强引用self
如果是instance variable: 强引用self
如果是self.property,强引用self
@interface Sample() @property (nonatomic) Date *dateVar; @end - (void)test { NSDate *date = self.dataVar; [function call:.... completion : ^{ [date timeIntervalSince1970]; //不会强引用self [_dataVar timeIntervalSince1970]; //强引用self [self.dataVar timeIntervalSince1970]; //强引用self; }]; }
Name Convention
对于bool property,如果要兼容kvc,那么getter方法要修改为isXXX,除了bool property,其他类型的完全没有必要另外定义名字。
相关文章推荐
- 黑马程序员_java11_多态
- Lucene--AttributeImpl
- C++ 文件读取
- hibernate 删除方式
- 应用程序体系结构 AppDomain 和动态加载 ShadowCopyFiles
- Hello JSP!——request对象
- 使用Kinect采集数据,去除数据中无用的数据
- LeetCode || First Bad Version
- js re cheatsheet
- phonegap 2.9.1生成cordova.jar文件
- 深入理解SQL的四种连接-左外连接、右外连接、内连接、全连接
- 非均衡数据集的分类问题
- 29个你必须知道的Linux命令
- 【读PPT】管中窥豹:用大数据洞察“用户画像”的秘密!
- 9.Android 万能ViewHolder
- CSS3中轻松实现渐变效果
- poj 2686 状压dp
- 怎样在codeblock中添加AStyle工具
- 深入分析看门狗框架(1)
- Linux下C++的多线程编程