IOS开发学习笔记(二十二)——ObjectC语言难以理解的概念汇总
来源:互联网 发布:mac 链接阿里云服务器 编辑:程序博客网 时间:2024/04/28 01:48
这篇文章将会对ObjectC语言中比较难理解的概念进行汇总,帮助我们更好的进行iOS开发。
方法&成员变量&属性
我们首先看一个很简单的方法代码:
- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;
- 方法名称你可以认为是dequeueReusableCellWithIdentifier_forIndexPath;
- 参数有两个,第一个是NSString *类型,名字叫identifier;第二个是NSIndexPath *类型,名字叫indexPath;
- 最顶头的减号("-")标识是object方法,如果是加号("+")标识是静态(static)方法;
- 属性通过@private定义,并且需要你自己去显式通过实现方法来存取,或者.h文件中指定@property,.m文件中指定@synthesize来使得可以通过self.propertyName访问;
- 可以指定readonly指示符指示仅生成get方法;
- 注意对于静态方法(类方法)可以使用self或者super关键字指定使用自己还是父类的静态方法;
属性
对于属性中可能使用到的几个关键字我们这样理解:
- nonatomic关键字说明这个是非原子操作的,所以可能是非线程安全的;
- strong和weak关键字在所指定的属性是对象类型时使用。strong表示保持这个对象的指针所指向的内存,一直到使用结束;weak表示如果没有人再使用这个指针,那么就设置为nil;官方的解释是这样滴:
strong is the default. An object remains “alive” as long as there is a strong pointer to it.
weak specifies a reference that does not keep the referenced object alive. A weak reference is set to nil when there are no strong references to the object.
另外还有一个比喻:
我们的属性可以认为是一条狗,他总是想逃跑;strong可以认为是狗链子,我们可以用多条链子拴住这条狗,只要有一条还抓在我们手里,狗就跑不了;而weak是一个看着狗的孩子,当链子在我们手中的时候,孩子可以看住狗,但是当链子不在我们手中时,狗就可以跑掉,尽管孩子在看着狗。
.h@interface ViewController : UIViewController@property (nonatomic, strong) MyType *obj1;@property (nonatomic, weak) MyType *obj2;@end
注意obj2是strong还是weak对程序运行结果的影响。
.m- (void)viewDidLoad{ [super viewDidLoad];// Do any additional setup after loading the view, typically from a nib. obj1 = [[MyType alloc] init]; obj2 = obj1; obj1 = nil; NSLog(@"obj2 = %@", obj2);}
注意weak是在iOS5以后引入的,所以如果你的代码需要在iOS4上面运行,你只能使用strong。 - 上面讲得实际上就是引用计数的概念,strong类型的对象会被加上引用计数,当最后一个对象不再保留引用计数的时候,strong的对象就会被自动释放,所以这个时间点相对垃圾回收机制来说是可预期的;
- 局部变量由于在方法执行结束后超出其作用于,所以会被自动清除引用计数;
- 对于非ARC的程序,weak对应的关键字是unretain,strong对应的是retain关键字;另外还有一个关键字unsafe_unretain这个会造成野指针,不推荐使用,就不赘述了;
- 所有的属性,在你没有设置默认的setter的时候,初始化的值都是0;
- 可以使用if (obj)判断对象是否是nil,但一般情况下你无须这样去做。对一个nil的对象做一个操作(例如调用一个方法)将不会真正去执行这个方法,如果这个方法是有返回值的,一般都会返回0;但是如果这个方法是返回一个C类型的结构值的,那么你需要自己去事先检查这个对象是否是nil,因为无法保证返回的结构中的成员变量是有效的还是无效的,可能是一堆垃圾数据;
对于如何使用方法/成员变量/属性,建议采用如下规则:
- 所有的实例变量都声明为:@private;
- 所有属性都是用@property定义,并在方法中采用self.property或者super.property的方式引用;
- .m文件中使用@synthesize使得编译器将setter和getter设置为与property同名的方法;
- 注意有这样的方法,可以强制你必须在代码中使用self.property的方式使用属性,在.m文件的interface段内这样写:
@interface MyViewController ()@property int myPriveteProperty;@end
这样你在方法中必须使用self.myPrivateProperty这样的方式来引用成员变量。 - 注意在对象使用前最好检测是否是nil,因为对于object.property的使用形式,如果object本身是nil,并且property本身是一个CType的一个结构类型变量,那么property本身的值是未知的,可能会导致不可预知的错误;
- 对于需要打印输出的对象,可以重写-(NSString *)description方法(类似于java中的toString),并且可以在NSLog()中使用%@输出;
变量类型
对于变量类型有几个需要注意的地方:
- Java中我们是可以定义一个String类型的变量(或者任意一个对象类型的变量),但在ObjectC中我们的对象必须使用指针类型定义:NSString *str;
- id类型返回任意一个对象类型的变量,类似于Object。但注意:返回的仍然是一个指针,类似于NSString *;
- 事件响应方法:IBAction返回值类似于void;
- 注意BOOL类型的变量是YES/NO,不再是TRUE/FALSE;
访问控制符
访问控制符有几个需要注意的,我列举如下:
- ObjectC的默认访问控制符是@protected的,当然你也可以定义为@private或者@public;
动态类型Dynamic Type
这里面最需要讨论的就是内省(Introspection):
- isKindOfClass对于有java经验的我来说很好理解,可以理解为一个类是否是一个另一个类或其父类的实例;
- isMemberOfClass就比较诡异了,是返回一个object是否这个类的实例,注意这里不检测继承关系,也就是说[teacher isMemberOfClass: [Teacher class]]返回YES,但是[teacher isMemberOfClass: [Person class]]返回NO。
注意看下面的代码:obj1 = [[MyType alloc] init]; NSLog(@"obj1 isKindOfClass:NSObject = %@", ([obj1 isKindOfClass:[NSObject class]]) ? @"YES" : @"NO"); NSLog(@"obj1 isMemberOfClass:NSObject = %@", ([obj1 isMemberOfClass:[NSObject class]]) ? @"YES" : @"NO"); NSLog(@"obj1 isMemberOfClass:MyType = %@", ([obj1 isMemberOfClass:[MyType class]]) ? @"YES" : @"NO");
- ObjectC中有一种特殊的表达式:[tester respondsToSelector:@selector(test:)],其中的@selector是一个SEL类型,前面的表达式表示检查tester这个object有没有提供一个名字叫"test"的方法,注意表达式上"test"后面是有冒号的;
注意另一个问题,如果一个对象被设置为nil,那么以上的这些操作对于这个对象来说返回都是NO;
集合类型
集合类型使用的时候需要注意:
- NSArray/NSDictionary/NSSet等都是不可变的集合类型,意思是在创建的时候就初始化内容,并且以后不可以再增加/删除内容;
- NSMutableArray/NSMutableDictionary/NSMutableSet等是可变集合,分别类似于Java中的数组/Map等集合类型;
总体来说,ObjectC和C/C++/Java这些语言有类似的地方,但差异较大,过渡过来的学习曲线还是比较陡峭的,但只要抓住差异注意理解,上手还不是那么难,关键在于理解。
- IOS开发学习笔记(二十二)——ObjectC语言难以理解的概念汇总
- IOS开发学习笔记(十二)——ObjectC中的复杂类型
- IOS开发学习笔记(一)——ObjectC语言快速入门
- IOS开发学习笔记(十一)——ObjectC中集合类型的使用
- iOS开发笔记之二十二——归档Archiver(二)
- IOS学习笔记(十二)之IOS开发之表视图(UITableView)的讲解与使用(二)
- iOS学习笔记(十二)——iOS国际化
- iOS学习笔记(十二)——iOS国际化
- object-c难以理解的一些概念
- Object-C难以理解的一些概念
- Object-C难以理解的一些概念
- Object-C难以理解的一些概念
- c语言学习笔记二十二
- Oracle学习笔记(二十二)——块
- 学习笔记(二十二)
- IOS开发ObjectC Block的实现方式
- Iphone开发基础篇(十二)-ObjectC之协议
- iOS小明开发笔记(二十二) (C语言之内存四区和函数调用模型)
- Oracle Spatial + Python
- db_block_checking与db_block_checksum
- JavaScript基础学习
- C++指针动态转换
- 【推荐】PHP上传文件大小限制大全
- IOS开发学习笔记(二十二)——ObjectC语言难以理解的概念汇总
- Maven常见问题
- Lesson02:HTML 5 视频
- 雷鸟(Thunderbird)收取Gmail出错,收到警告邮件
- 用BC命令做简单的benchmark
- nise_bosh在openstack上搭建cloudfoundry中cf.yml的完整版
- Nginx模块开发指南(Emiller) 二
- streams table级别复制
- 盒子游戏(湖南省第七届大学生计算机程序设计竞赛)