A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

#pragma mark - Day06_01_点语法

1.点语法是一个编译器特性

编译器在编译的时候,会把点语法转换成对应的getter和setter

如果是赋值(写在等号的左边),调用setter

如果是取值(写在等号的右边),调用getter

点语法的本质还是getter和setter,而不是直接访问成员变量


2.注意点

    1.在定义getter和setter的时候,要慎用点语法,否则可能会造成死循环

    记住一句话:在getter和setter当中,直接访问成员变量(比如_age),不要使用其他手段

    如果一个函数或者方法自己调用自己, 递归,递归必须要有一个出口,防止死循环

    2.如果没有给一个成员变量封装getter和setter,那么就不能使用点语法

    3.在给成员变量封装setter和getter的时候,一定要注意命名规范,否则无法使用点语法


@interface HMPerson: NSObject

{

    int _age;

}

- (void)setAge:(int)age;

- (int)age;


@end


HMPerson *person = [HMPerson new];

int a = [person age];

person.age = 10;

int a = person.age;


// 不使用点语法,给变量做自加操作,需要三步

int a = [person age];

a++;

[person setAge:a];


// 使用点语法做自加操作

person.age++;


person.age = person.age + 1;


#pragma mark - Day06_02_@property的使用

Xcode4.3之前

Xcode是一个IDE,集成的软件开发工具,肯定是包含了编译器


1.@property是一个编译器特性

作用:自动生成成员变量的getter和setter的声明

是写在@interface中的


2.使用规范

@property 成员变量类型 去掉下划线的成员变量名


3.内部原理:

    1.生成setter方法声明

    2.生成getter方法声明


4.注意:

    1.@property声明的类型一定要和成员变量类型一致

    2.@property声明的名称一定要符合规范,成员变量名去掉下划线,只有这样生成的getter和setter方法声明才符合规范

    3.@property可以批量声明类型相同的成员变量


#pragma mark - Day06_03_@synthesize的使用

1.@synthesize是一个编译器特性

作用:自动生成成员变量的getter和setter的实现

是写在@implementation中的


2.使用规范

@synthesize 对应的@property的名称


3.内部原理

    1.在@implementation的大括号中,生成一个和@property同名的成员变量,这是一个真正私有的成员变量,没有使用_开头

    2.实现setter方法,在方法内部,直接给给它自己生成的成员变量赋值

    3.实现getter方法,在方法内部,直接返回它自己生成成员变量


#pragma mark - Day06_04_@synthesize的使用注意


1.因为@synthesize会自动在@implementation生成和@property同名的成员变量,所以我们如果没有在@interface中手动定义成员变量,也可以正常使用

2.如果不想让@synthesize自动生成成员变量,而是使用自己定义的成员变量,这个时候可以单独指定

    1.在@interface中自己声明成员变量

    2.在@synthesize后面指定需要使用的变量.格式: @synthesize 对应的@property的名称 = 成员变量


3.注意:

    1.@synthesize后面的名称一定是在@interface中声明的@property名称

    2.@synthesize可以自动的生成setter和getter的实现,但是在实现中没有逻辑判断,只是单纯的赋值.如果你需要在赋值的时候进行判断,那么重写@synthesize自动生成的方法即可

    3.@synthesize可以批量声明不同类型的变量


举例:

@interface HMPerson : NSObject

{

    NSString *_name;

}

@property NSString *name;

@end


@implementation HMPerson

@synthesize name = _name;

@end


4. 编译器特性:

    1.点语法:简化getter和setter的调用

    2.@property:简化getter和setter的声明

    3.@synthesize:简化getter和setter的实现


以上所有内容,都是Xcode4.3之前的特性


在Xcode4.4之后,不需要使用@synthesize了,有一种更加简单的形式


#pragma mark - Day06_05_@property的增强使用

在Xcode4.4之后,苹果对@property进行了增强

1.在@implementation中生成一个和@property类型相同,在@property名字前添加下划线的私有成员变量

2.自动生成该变量的getter和setter的声明

3.自动生成该变量的getter和setter的实现,但是在方法的实现内部没有逻辑判断,如果想进行判断,自己重写即可.

4.@property只能写在@interface和@end之间


#pragma mark - Day06_06_使用@property增强注意

1.使用@property生成的成员变量和@property中声明的类型一致

2.@property可以批量声明类型相同的变量,但是不推荐使用,建议大家分来写,这是一个规范

3.@property自动生成的setter和getter实现是没有逻辑判断的,如果想进行判断,自己重写即可

    1.如果只重写setter,那么会自动生成私有的成员变量以及getter

    2.如果只重写getter,那么会自动生成私有成员变量以及setter

    3.如果同时重写了getter和setter,那么不会自动生成成员变量


就业班的课程里面,@property,根据某些需求,重写set方法,或者重写get方法


4.以后开发中

    1.使用@property自动声明成员变量以及对应的getter和setter的声明和实现

    2.使用点语法快速调用getter和setter



"补充

5.@property只有写在@interface和@end之间的时候,才会做三件事情

@interface

@end

@implementation

@end


OC中还有其它特殊的语法:分类\协议,当在这些地方使用@property的时候,会做不同的事情


6.@property中可以通过参数说明生成成员变量的特性

参数有三种类型:

1.线程相关

    nonatomic 线程不安全的

    atomic 线程安全的

2.内存管理相关,说明使用什么样的内存策略

    assign

    retain

    copy

    strong

    weak

3.说明读写特性

    readonly


@property (nonatomic, copy) NSString *name;

@property (nonatomic, copy, readonly) NSString *name;


@property NSString *name;


点招面试的时候,

1.是什么

2.有什么作用

3.怎么使用

4.注意点


#pragma mark - Day06_07_任意的指针可以指向任意的对象

1.OC是一门弱语法的语言

  OC是一门动态的语言,只有在运行的时候,才能确定真实的类型


2.静态语言:指针指向本类以及本类的子类对象

    动态语言:指针可以指向非本类对象


3.指针就是存地址的,所以一个指针变量占据8个字节,可以存任意的地址



#pragma mark - Day06_08_编译检查

1.编译检查:编译的时候,编译器会检查代码是否符合语法规范.

2.根据这个特性,可以通过强制类型转换,欺骗编译器


#pragma mark - Day06_09_运行检查

1.运行检查:运行的时候,会真正的去检查对象中是否存在这个方法



NSString *str = [HMPerson new];

[(HMStudent *)str study];


// 编译的时候,只是去检查这个指针类型中是否存在方法的声明,如果没有说则明无法调用,这是一个语法问题

// 运行的时候,实际上是通过指针中存储的地址访问堆区空间的对象,如果发现该地址对应的对象,没有实现该方法,程序会崩溃

崩溃时会报一个非常经典的错误

unrecognized selector sent to instance 0x100306b30


#pragma mark - Day06_10_NSObject万能指针

NSString *str = [HMPerson new];

[str sayHi]


1.NSObject是OC中所有类的基类 == OC中所有的类都是从NSObject派生出来的

2.根据LSP,NSObject类型的指针,可以指向所有的子类对象(可以指向任意类型的对象)

但是默认情况下,只能调用NSObject类中的方法

NSObject *obj = [HMPerson new];


#pragma mark - Day06_11_id指针

1.id和NSObject类型指针的区别

    1.使用NSObject类型的指针,会进行编译检查

    2.使用id类型的指针,不会进行编译检查


2.id的局限性

    1.id类型的指针不能使用点语法,只能使用[]的形式调用方法

    2.id类型的指针不需要进行编译检查,但是需要进行运行检查


#pragma mark - Day06_12_id指针总结

id的本质

通过id可以指向任意的对象

void *

可以理解为OC中的id相当于C语言中的void *


id person = [NSString string];

[person length];

[person count];


#pragma mark - Day06_13_instancetype

1.为了在父类中定义类方法,返回当前类的对象.

+ (instancetype *)person {

    return [self new];

}


2.instancetype是什么

是一个类型


3.instancetype的作用

代表方法返回值的类型,这个方法通过哪个类调用,就代表返回的是哪个类的对象


4.instancetype怎么用

只能作为方法的返回值


5.注意点:

instancetype和id的区别

instancetype只能作为方法的返回值,不能用在其它场合,代表返回值的类型是当前类的对象

id是一个可以指向任意类型的指针,id是一个无类型的指针,可以使用id声明一个指针变量


#pragma mark - Day06_14_在对象方法中使用self创建当前类的对象

1.在对象方法中,self指向当前对象

2.可以使用self调用class方法,获得当前对象的类

3.使用当前对象的类,创建一个对象

- (instancetype)test {

    return [self.class new];

}


#pragma mark - Day06_15_动态类型检测

1.动态:程序运行的时候(代码执行的时候)


2.在NSObject类中,有以下四个常用方法

// 判断当前对象是否 "拥有" 或者 "实现" 了指定的方法

// 只要有方法的实现,就没有任何的问题,返回值是YES

// 此方法必须要掌握,后面会频繁使用

- (BOOL)respondsToSelector:(SEL)aSelector;


// 以下三个方法了解即可

// 判断当前对象是否是指定类及其子类的类型

- (BOOL)isKindOfClass:(Class)aClass;

// 判断当前对象是否是指定类型(不包括其子类)

- (BOOL)isMemberOfClass:(Class)aClass;

// 判断当前类是否是指定类的子类

+ (BOOL)isSubclassOfClass:(Class)aClass;


#pragma mark - Day06_16_构造方法简介

1.new方法的本质

new方法中其实调用了两个两个方法:alloc和init

2.alloc的作用:

在堆区开辟一个合适的区域,创建对象


3.init的作用

    1.初始化对象,给对象的成员变量赋默认值:

        OC指针:nil

        C指针:NULL

        基本数据类型:0

    2.非常重要的,必不可少的,但是我们未知的事情


#pragma mark - Day06_17_重写init方法

1.为什么要重写init方法

    1.如果想让对象创建出来之后,其中的成员变量不是默认值,而是自己制定的值

    2.如果想让对象创建出来的时候,做一些事情

2.怎么重写

目的:在父类的init方法的基础上扩展一些内容:(1.给成员变量赋指定的值;2.在初始的时候做一些事情)

    1.先调用父类的init方法

    2.父类的init方法,返回值是instancetype,也就是调用方法的对象对应类型的指针

    3.判断父类的init方法是否执行成功,如果执行成功,就进行扩展,否则什么也不做

    4.返回当前对象

3.规范


- (instancetype)init {

    self = [super init ];

    if (self) {

        // 给当前对象的成员变量赋指定的值

        self.age = 1;

        self.name = xiaoming

    }

    return self;

}



1. [HMPerson alloc] init]

2.

#pragma mark - Day06_18_自定义构造方法

1.格式规范

- (instancetype)initWithName:(NSString *)name andAge:(int)age {

   

    // 对象中的成员变量

    self = [super init];

    if (self) {

        // 给当前对象的成员变量赋指定的值

        self.age = age;

        self.name = name;

    }

    return self;

}


HMPerson *p = [HMPerson alloc ] init];

nil sayHi]

2.注意

    1.init方法也叫构造方法

    2.在OC里面,只有以init或者initWith开头的方法,编译器才认为是构造方法,才能在其中给self赋值


HMPerson

+ (instancetype)personWithName:(NSString *)name andAge:(int)age {

//    HMPerson *person = [self new];

//    person.name = name;

//    person.age = age;

    return [[self alloc] initWithName:name andAge:age];

}




0 个回复

您需要登录后才可以回帖 登录 | 加入黑马