6 OC基础06
来源:互联网 发布:长期股权投资转换知乎 编辑:程序博客网 时间:2024/05/16 04:43
6 OC基础06
特有语法
1,点语法
本质:非赋值,只是在调用set方法的时候调用set方法,在调用get方法的时候调用get方法.
- 作用:快速调用get,set方法.
- 语法:对象名.去掉下划线的属性名.
p1.name = @"Rose";
注意:* 在set,get实现方法内部慎用点语法(很可能造成死循环)*,可以使用箭头调用
2,@property的使用
@property属性生成器
3,@synthesize
* 4.4之前 *
- @property作用:自动生成set,get方法的声明.
- @synthesize作用:自动生成set,get方法的实现 (这个时候生成的属性是不带下划线的不是我们所需要的).
注意:要使用@synthesize 属性名 = _@property中的属性名.这种格式.
* 4.4之后 *
4,@property增强
@property的属性是真私有属性,只能在点语法中使用(其实是调用方法),箭头访问在外部无法看见也无法使用.
- 实现逻辑验证可以自己重写get,set方法.
- 不能同时重写一个属性的get,get这样会报错.
- 不写@property:
- 属性只用于内部访问,用自己设置的真私有属性.
重写set,get方法:
5,动态类型和静态类型(指针类型)
OC是一门弱语言,编译器在检查时没那么严格,很容易通过.
弱语言的优点:自由灵活
缺点:出了错误之后很难找.强语言优点:不自由
缺点:提前发现错误
OC是一门动态语言,运行才会报错,编译很多都不会报错.
静态类型:ZLPerson *p1 = [ZLPerson new];
动态类型:ZLPerson *p2 = [ZLStudent new];
在OC中任意指针指向任意类型对象,最多只是警告,不会报错.(指针都是八个字节,可以储存任何对象的地址)
6,编译检查-等号左边
编译器(LLVM)在编译源代码时,检查语法错误.指针对象调用方法(找指针的类型的类有没有这个方法,没有,报错,通不过编译)可以通过强制类型转换来骗过编译器.强制类型转换以后属性可以通过get,set方法访问,但是不能通过点语法访问.
7,运行检查-等号右边
程序在运行的时候,当要调用这个指针指向的对象时,依然会做一个检查.回去检查这个指针指向的对象是否有这个方法,如果没有就报错.
所以:
1. 编译检查只是检查指针类型.
2. 运行检查是检查对象有没有这个方法,没有还是会报错.编译成功,并不代表没有问题.
8,NSObject指针
- NSobject是所有类的基类.
- c不是对象.
NSObject指针可以当做万能指针.
- c不是对象.
9,id指针(内部已经加*了)
- id指针是一个万能指针,指向任意的对象.
区别:
a.当指针类型为OBJect类型时,编译器会做编译检查,可能要进行强制类型转换.
b.id不会编译检查(特性:直接跳过)
* 局限性:只能调用方法,不能用点语法.如果使用要进行强转 *其他类型指针(父类)也不可以用点语法,除了instancetpe返回当前对象的才可以.
以后尽量使用id代替OBJect.
10,instancetype
区别:
都能作为返回值,instancetype能精准返回对象类型返回值.
id是一个万能指针,躲过编译检查,不仅可以作为方法的返回,还可以用来定义类型,instancetype则只能作为返回值.
- 父类构造对象方法,返回值为父类的指针类型,子类调用方法,创建的是一个父类对象,怎么解决?
当子类调用方法创建的是一个父类对象,怎么解决这个问题 + (id)person{ return [ZLPerson new]; }
标准的在类方法中,因为子类有可能继承这个方法,所以子类创建对象时也最好是子类的.用self创建.
当子类调用方法用self创建对象,解决了这个问题 + (id)person{ return [self new]; }
但是要接受这个类创建的对象,可以用任何类型的指针去接受,这显然不合逻辑(对象可以用NSString来接受,因为返回的是一个id类型),怎么解决这个问题
当子类调用方法创建对象用self,且返回instancetype类型,解决了这个问题 + (instancetype)person{ return [self new]; } 代表返回值是当前类的对象,不是任意对象了.最常规的写法
11,动态类型检测
需求:编译检查时,只是检查指针类型,希望检查这个指针指向的对象有没有这个方法.
方法一:对象中有没有这个方法 BOOL a =[stu respondsToSelector:@selector(run)]; 方法二:对象是不是某个类的对象,包括子类 BOOL b = [stu isKindOfClass:[ZLStudent class]]; 方法三:对象是不是某个类成员,不包括子类 BOOL c = [stu isMemberOfClass:[ZLStudent class]]; 方法二:前面类是不是后面类的子类 BOOL d = [ZLPerson isSubclassOfClass:[ZLStudent class]];
12,构造方法
Person *p1 = [[Person alloc]init];
注意:创建对象* 务必要初始化对象 *,因为init除了初始化,还做了另外的申请,如果为init可能将导致问题.
13,重写构造方法
- (instancetype)init{ //1,先调用父类的init方法,因为父类方法做了出了初始化之外的东西,你init仅仅给他初始化属性他的其他的东西就被你抹掉了,所以一定要重写! //2,可能调用父类的init方法会失败,需要做判断 //3,现在才可以重写init方法了 //4,返回重写的对象. if ([super init]) { self.age = 18; } return self;}
14,自定义构造方法
- (instancetype)initWithAge:(int)age{ if ([super init]) { self.age = 19; } return self;}
如果父类自定义构造方法了,子类再重写或自定义构造方法的时候,super调用的就是父类自定义构造方法,而不是[super init].
- 6 OC基础06
- OC基础笔记6
- OC---oc基础入门
- OC基础
- oc基础
- OC 基础
- OC基础
- OC基础
- OC基础
- oc基础
- OC基础
- oc基础
- OC基础
- oc基础
- OC基础
- OC基础
- OC基础
- OC基础
- 第8周项目4-字符串加密
- 登录vpn提示没有安装java
- function-style conversion to builtin type takes only one argument
- QT读取剪贴板信息和拖动文件到程序以(拖动音乐播放为列)
- 随笔
- 6 OC基础06
- python 学习--定制类
- GCD的一些简单使用
- react-native打离线bundle包
- oracle卸载重装,碰到问题,“[INS-07009] 无法加载 BeanStore”
- 求s = a+aa+aaa+aaaa+a......a的值,其中a是一个数字
- ADB 出现 offline
- 7 OC加强01
- git-标签管理