------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
一、点语法
1、什么是点语法?
@点语法其实就是方法调用,对普通方法
@当使用点语法时,编译器会自动展开成相应的方法
示例
- Person *p = [Person new];
- // 点语法的本质还是方法调用
- p.age = 10; // [p setAge:10];
- int a = p.age; // [p age];
- p.name = @"Jack";
- NSString *s = p.name;
- NSLog(@"%@", s);
一下方法会引发死循环,因为方法调用了自己
- - (void)setAge:(int)age
- {
- //_age = age;
- NSLog(@"setAge:");
- // 会引发死循环
- //self.age = age; // [self setAge:age];
- }
- - (int)age
- {
- NSLog(@"age");
- return _age;
- // 会引发死循环
- //return self.age;// [self age];
- }
1、成员变量有四种作用域,分别为@protected、@public、@private、@package
2、解释
@protected:默认成员变量类型,只能在当前类的对象方法中直接访问
@protected:可以在当前类以及子类的对象方法中直接访问
@public:任何地方都可以直接访问,非常不安全,一般不使用
@package:同一个“体系内”(框架)可以访问,介于@private和@public之间,(暂时很少用到)
三、set方法和get方法的快速生成
set方法和get方法的代码重复性书写大大降低了程序员工作的效率
OC语法中使用@property和@synthetic方法大大简化了set方法和get方法的定义和声明
@property:
在.h文件中的@interface中使用,用来声明(和定义)set和get方法
示例:
- @property int age;
- //- (void)setAge:(int)age;
- //- (int)age;
- @property int height;
- //- (void)setHeight:(int)height;
- //- (int)height;
- @property double weight;
- @property NSString *name;
在.m文件中的@implementation中使用,用来实现set和get方法
- @synthesize age = _age;
- //就可以代替
- //- (int)age{
- // return _age;
- //}
如果已经使用了@property方法可以不使用synthetic方法
四、万能指针,可以指向任何OC对象类型的指针
- //定义
- id p = [Person new];
1、为什么要使用构造方法:为了让对象创建出来,成员变量就会有一些固定的值
Person *p = [Person new];显然不能满足这个需求
2、够着方法的初步认识:
@调用+alloc分配存储空间
@调用-init进行初始化
@合并起来可以完整的创建一个对象
- Person *p1 = [Person alloc];
- Person *p2 = [p1 init];
- Person *p4 = [[Person alloc] init];
@ 一定要调用回 super 的 init 方法 : 初始化父类中声明的一些成员变量和其他属性
@如果对象初始化成功,才有必要进行接下来的初始化
@返回一个已经初始化完毕的对象
示例:
- - (id)init
- {
- if ( self = [super init] )
- { // 初始化成功
- _age = 10;
- }
- // 返回一个已经初始化完毕的对象
- return self;
- }
自定义构造方法的规范
@一定是对象方法,一定以 - 开头
@返回值一般是id类型
@方法名一般以initWith开头
实例演示:@自定义构造方法的声明Person类
定义name和age成员变量并生成相应的构造方法和能够初始化两个成员变量的构造方法
- - (id)initWithName:(NSString *)name;
- - (id)initWithAge:(int)age;
- - (id)initWithName:(NSString *)name andAge:(int)age;
- - (id)initWithName:(NSString *)name
- //能够初始化name的构造方法
- {
- if ( self = [super init] )
- {
- _name = name;
- }
- return self;
- }
- - (id)initWithAge:(int)age
- //能够初始化age的构造方法
- {
- if ( self = [super init] )
- {
- _age = age;
- }
- return self;
- }
- - (id)initWithName:(NSString *)name andAge:(int)age
- //能够同时初始化name和age的构造方法
- {
- if ( self = [super init] )
- {
- _name = name;
- _age = age;
- }
- return self;
- }
5子类的继承和实现
定义一个Student类继承Person对象并增加一个no成员变量和一个能同时初始化3个成员变量的构造方法
- #import "Person.h"
- @interface Student : Person
- //继承Person类
- @property int no;
- - (id)initWithNo:(int)no;
- - (id)initWithName:(NSString *)name andAge:(int)age andNo:(int)no;
- //新增变量和构造方法
- @end
- #import "Student.h"
- @implementation Student
- - (id)initWithNo:(int)no
- {
- if ( self = [super init] )
- {
- _no = no;
- }
- return self;
- }
- // 父类的属性交给父类方法去处理,子类方法处理子类自己的属性
- - (id)initWithName:(NSString *)name andAge:(int)age andNo:(int)no
- {
- // 将name、age传递到父类方法中进行初始化
- if ( self = [super initWithName:name andAge:age])
- {
- _no = no;
- }
- return self;
- }
- @end
1、用法:在不改变原来类的情况下增加新的补充有两种方法
1)分类:分类只能增加方法
2)继承:继承可以增加成员变量和方法
2、格式:@interface 类名 (分类)
//方法声明
@end
@implementation 类名 (分类)
//方法的实现
@end
3、用途在开发一个庞大的类的时候一个类有多个人开发,有利于团队合作
实例演示->分类的应用:
给NSString增加一个类方法:计算某个字符串中阿拉伯数字的个数
给NSString增加一个对象方法:计算当前字符串中阿拉伯数字的个数
@分类的声明
- #import <Foundation/Foundation.h>
- //.h文件
- @interface NSString (Number)
- + (int)numberCountOfString:(NSString *)str;
- //类方法
- - (int)numberCount;
- //对象方法
- @end
- #import "NSString+Number.h"
- //.m文件
- @implementation NSString (Number)
- + (int)numberCountOfString:(NSString *)str
- {
- return [str numberCount];
- //对象方法被类方法调用
- }
- - (int)numberCount
- {
- int count = 0;
- for (int i = 0; i<self.length; i++)
- {
- // 取出i这个位置对应的字符
- unichar c = [self characterAtIndex:i];
- // 如果这个字符是阿拉伯数字
- if ( c>='0' && c<='9' )
- {
- count++;
- }
- }
- return count;
- }
- @end
七、类的本质
类的本质就是一个Class类型的对象“类对象”
typedef struct objc_class *Class
八、description方法
1、什么是description方法?当NSLog调用某个类对象或者对象时就会调用类的discretion方法
2、description方法的注意,不要在NSLog中使用self,会进入死循环。
3、实例演示:下面方法输出一个字符串Abc
- //类.m中的实现
- + (NSString *)description
- {
- return @"Abc";
- }
- //mian.m文件中的调用
- Person *p = [[Person alloc] init];
- NSLog(@"%@", p);//默认情况下是输出<类 地址>
修改上述代码中的类.m文件中的description方法即可
- - (NSString *)description
- {
- return [NSString stringWithFormat:@"age=%d,name=%@", _age, _name]
- }
1、sel方法的用途
@每个类方法的列表都存储在类对象中
@每个方法都有与之相对应的sel类型对象
@根据sel对象就可以找到方法的地址,进而调用方法
2、sel方法的创建
SEL s1 = @selector(test);
[p performSelector:@selector(test)];
十、习题练习
练习题1
- /****************************************************************************
- * 题目:改错1
- ****************************************************************************/
- #import <Foundation/Foundation.h>
- @interface Person : NSObject
- @property int age;
- @end
- @implementation Person
- //+ (NSString *)description
- //{
- // return [NSString stringWithFormat:@"_age=%d", _age];
- //}
- //1.类方法不可以调用成员变量
- - (NSString *)description
- {
- return [NSString stringWithFormat:@"_age=%d", _age];
- }
- @end
- /****************************************************************************
- * 题目:改错2
- ****************************************************************************/
- #import <Foundation/Foundation.h>
- @interface Person : NSObject
- - (void)test;
- @property int age;
- @end
- @implementation Person
- - (void)test
- {
- //1.死循环
- // [self performSelector:_cmd];
- }
- @end
- int main()
- {
- // id *p = [[Person alloc] init];
- // 2.id后面不能加*(自带*)
- id p = [[Person alloc] init];
- [p setAge:10];
- // p.age = 10;
- // 3.id类型对象不能使用点语法(自带*)
- Class c = [Person class];
- // [c test];
- // 4.c类对象应该调用类方法而不是对象方法
- return 0;
- }
- /****************************************************************************
- * 题目:分析题1
- ****************************************************************************/
- #import <Foundation/Foundation.h>
- //Persong类的声明,定义了一个age成员变量
- @interface Person : NSObject
- @property int age;
- @end
- @implementation Person
- //实现了一个类description方法输出A
- + (NSString *)description
- {
- return @"A";
- }
- //实现了一个对象description方法输出B
- - (NSString *)description
- {
- return @"B";
- }
- @end
- int main()
- {
- Person *p = [Person new];
- Person *p2 = [[Person class] new];
- NSLog(@"%@", p);
- // 输出B
- NSLog(@"%@", p2);
- // 输出B
- NSLog(@"%@", [Person class]);
- // 输出A
- NSLog(@"%@", [p class]);
- // 输出A
- return 0;
- }
- /****************************************************************************
- * 题目:分析题2
- ****************************************************************************/
- //2.类的加载过程
- #import <Foundation/Foundation.h>
- @interface Person : NSObject
- @end
- //声明Person类
- @interface Student : Person
- @end
- //声明Student类
- @interface GoodStudent : Student
- @end
- //声明Student类的子类GoodStudent;
- //主函数
- int main()
- {
- Student *s = [[Student alloc] init];
- NSLog(@"%@", s);
- // 1、先调用父类的description方法,再调用类本身的description方法,再调用分类的description方法
- // 2、先调用description方法再调用initialize方法,调用initialize方法次序如上
- // 3、最后输出系统默认的<类: 类的地址>
- return 0;
- }
- //1、Student类的实现
- @implementation Student
- + (void)load
- {
- NSLog(@"Student+load");
- }
- + (void)initialize
- {
- NSLog(@"Student+initialize");
- }
- @end
- //2、GoodStudent (MJ)分类的实现
- @implementation GoodStudent(MJ)
- + (void)load
- {
- NSLog(@"GoodStudent-MJ+load");
- }
- + (void)initialize
- {
- NSLog(@"GoodStudent-MJ+initialize");
- }
- @end
- //3、GoodStudent类的实现
- @implementation GoodStudent
- + (void)load
- {
- NSLog(@"GoodStudent+load");
- }
- + (void)initialize
- {
- NSLog(@"GoodStudent+initialize");
- }
- @end
- //4、Person类的实现
- @implementation Person
- + (void)load
- {
- NSLog(@"Person+load");
- }
- + (void)initialize
- {
- NSLog(@"Person+initialize");
- }
- @end