黑马程序员-iOS基础-Objective-C基础(五)核心语法(下)

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

黑马程序员-iOS基础-Objective-C基础(五)

核心语法(下)

 1、构造方法

是对象的对象方法,用在类中

构造方法是用来初始化对象的方法,- 开头

如:创建对象[类名 new]

	Person *p = [Person new];
	/*
	完整的创建一个可用对象
	1.分配存储空间  +alloc类方法
	2.初始化  -init对象方法
	*/
	//[Person new]等价于以下两句
	//1.调用+alloc分配存储空间
	Person *p1 = [Person alloc];
	//2.调用-init进行初始化
	Person *p2 = [p1 init];
	//以上两句可以缩写成:
	Person *p3 = [[Person alloc] init]; // 常用,有的情况下不一定会使用-init方法进行初始化

重写构造方法的目的

让对象创建出来,成员变量就会有一些固定的值

重写构造方法的注意点

1.调用父类的构造方法[super init]

2.再进行子类内部成员变量的初始化

子类父类-init方法执行过程

构造方法代码举例

Person.h

#import <Foundation/Foundation.h>

@interface Person : NSObject

@property int age;

@end


Person.m

#import "Person.h"

@implementation Person

- (id)init // 重写-init方法
{
	/*
	// 1.一定要调用回super的init方法:初始化父类中声明的一些成员变量和其他属性
	self = [super init]; // 当前对象 self
	// 2.如果对象初始化成功,才有必要进行接下来的初始化
	if(self != nil)
	{
		//初始化成功
		_age = 10;
	}
	// 3.返回一个已经初始化完毕的对象
	return self;
	*/
	//可以简写为:以后用这种
	if(self = [super init])
	{
		_age = 10;
	}
	return self;
}

@end


main.m

#import <Foundation/Foundation.h>
#import "Person.h"

int main(int argc, char const *argv[])
{
	Person *p = [Person new];
	/*
	完整的创建一个可用对象
	1.分配存储空间  +alloc类方法
	2.初始化  -init对象方法
	*/
	//[Person new]等价于以下两句
	//1.调用+alloc分配存储空间
	Person *p1 = [Person alloc];
	//2.调用-init进行初始化
	Person *p2 = [p1 init];
	//以上两句可以缩写成:
	Person *p3 = [[Person alloc] init]; // 常用,有的情况下不一定会使用-init方法进行初始化

	//要求每个Person对象创建出来,他的_age都是10,重写-init方法
	Student *stu = [Student new];
	return 0;
}


自定义构造方法

初始化时根据需要提供不同的变量得到不同的初始化结果

父类的属性交给父类方法处理,子类方法处理子类的属性

举例:

Person.h

#import <Foundation/Foundation.h>

@interface Person : NSObject

@property NSString *name;
@property int age;

/* 自定义构造方法的规范
1.一定是对象方法,一定以 - 开头
2.返回值一般是id类型
3.方法名一般以initWith开头
*/
- (id)initWithName:(NSString *)name;
- (id)initWithAge:(int)age;
- (id)initWithName:(NSString *)name AndAge:(int)age;
@end


 

Person.m

#import "Person.h"

@implementation Person

- (id)init // 重写-init方法
{
	//可以简写为:以后用这种
	if(self = [super init])
	{
		_name = @"Jack";
	}
	return self;
}
//自定义构造方法
- (id)initWithName:(NSString *)name
{
	if(self = [super init])
	{
		_name = name;
	}
	return self;
}
- (id)initWithAge:(int)age
{
	if(self = [super init])
	{
		_age = age;
	}
	return self;
}
- (id)initWithName:(NSString *)name AndAge:(int)age
{
	if(self = [super init])
	{
		_name = name;
		_age = age;
	}
	return self;
}

@end


 

Student.h

#import "Person.h"

@interface Student : Person

@property int no;

- (id)initWithNo:(int)no;
- (id)initWithName:(NSString *)name andAge:(int)age andNo:(int)no;

@end


 

Student.m

#import "Student.h"

@implementation Student

// 学生对象初始化完毕后,年龄是10,学号是1
- (id)initWithNo:(int)no
{
	if(self = [super init])
	{
		_no = no;
	}
	return self;
}

- (id)initWithName:(NSString *)name andAge:(int)age andNo:(int)no
{
	/*
	if(self = [super init])
	{
		_no = no;
		self.name = name; // [self setName:name]
		self.age = age; // [self setAge:age]
	}
	*/
	if(self = [super initWithName:name AndAge:age]) // 如果父类的成员变量应该尽量调用父类方法进行处理,可以避免父类变量改变后还需要在子类中修改
	{
		_no = no;
	}
	return self;
}

@end


 

main.m

#import <Foundation/Foundation.h>
#import "Person.h"
#import "Student.h"


int main(int argc, char const *argv[])
{
	Person *p = [[Person alloc] initWithName:@"Rose"];
	Student *stu = [[Student alloc] initWithName:@"Jim" andAge:15 andNo:7];

	NSLog(@"Name=%@, Age=%d, No=%d", stu.name, stu.age, stu.no);
	return 0;
}

更改Xcode模版

路径:应用程序-Xcode.app-右键显示包内容-Contents-Developer-Library-Xcode-Templates

2、分类Category

分类依赖于类,不允许修改原类、不允许继承的情况下给类扩充方法

格式:声明/实现

//声明
@interface 类名 (分类名称)

@end
//实现
@implementation 类名 (分类名称)

@end


文件名: "类名+分类名".h/.m

分类命名规则:分类名一般是作者姓名或者模块功能名称

作用:在不改变原来类内容的基础上,可以为类增加一些方法

使用注意

分类只能增加方法,不能增加成员变量;如果想添加变量,可以考虑继承

分类方法实现中可以访问原来类中声明的成员变量

分类可以重新实现原来类的方法,但是会覆盖掉原来的方法,会导致原来的方法失效

分类方法优先级最高,原来类/父类中同名的方法会被分类覆盖掉(不推荐)

方法调用的优先级:分类(最后参与编译的分类优先)-原来类-父类

好处

一个庞大的类可以分模块开发

一个庞大的类可以由多个人来编写,更有利于团队合作

练习:给NSString增加方法

#import <Foundation/Foundation.h>

/*
1.给NSString增加一个类方法:计算某个字符串当中阿拉伯数字的个数
2.给NSString增加一个对象方法:计算当前字符串中阿拉伯数字的个数
*/
//仅实现
@implementation NSString (Number)
//给NSString增加一个类方法:计算某个字符串当中阿拉伯数字的个数
+ (int)numberCountOfString:(NSString *)string
{
	int count = 0;
	for(int i=0;i<string.length;i++)
	{
		//取出i位置的对应字符
		unichar c = [string characterAtIndex:i];
		if(c >= '0' && C <= '9') // c >= 48 && C <= 57
		{
			count++;
		}
	}
	return count;
}
//给NSString增加一个对象方法:计算当前字符串中阿拉伯数字的个数
- (int)numberCount
{
	return [NSString numberCountOfString:self];
}
@end


3、类的深入研究

 类的本质

  类本身也是一个对象,是个class类型的对象,简称类对象

  类对象 == 类

  用Class创建类对象

  利用类对象创建类类型对象

  获取内存中的类对象

   Class c=[p class];
   Class c2 = [Person class];

 类的加载过程

  1.当程序启动的时候,就会加载一次项目中所有的类和分类

  类加载完毕后就会调用+ (void)load方法,只会调用一次

  2.当第一次使用这个类的时候(如创建对象),就会调用一次+ (void)initialize

  3.先加载父类,再加载子类(先调用父类的+load方法,再调用子类的+load方法)

     先初始化父类,再初始化子类(先调用父类的+initialize方法,再调用子类的+initialize方法)

4、description方法

 打印OC对象用%@

 -description

  默认情况下,利用NSLog和%@输出对象时结果是:<类名:内存地址>

   1.调用对象的-description方法

   2.拿到-description方法的返回值(NSString *)显示到屏幕上

   3.-description方法默认返回值是“类名+内存地址”

   决定了实例对象的输出结果

 +description

  用NSLog和%@输出类的信息

   1.会调用类的+description方法

   2.拿到+description方法的返回值(NSString *)显示到屏幕上

   决定了类对象的输出结果

 如果要用NSLog(@"%@",p);打印出p的所有属性,就需要重写+/-description方法

 注意:不要在description输出self,会死循环

5、NSLog补充

 对象内存地址%p

 NSLog(@"%p", p);取出p所指向对象的地址

 NSLog(@"%p", &p);取出p的地址

 NSLog(@"%@", &p); <类名: 对象地址>

 用NSLog输出C语言字符串时,不能有中文,否则无法显示

6、SEL数据类型

 一个SEL类型的数据就对应一个方法地址

 SEL是对方法的一种包装,将方法包装成一个SEL类型的数据,去找对应的方法地址,找到方法地址就可以调用方法

 当对象调用方法时

  1.把方法名包装成SEL类型的数据
  2.根据SEL数据找到对应的方法地址
  3.根据方法地址调用对应的方法

 调用方法的方式

  [对象名 performSelector:@selector(方法名)];
  [对象名 方法名];  (有的方法名包括冒号)

 每个方法中都有一个隐藏的_cmd,代表着当前方法

 NSStringFromSelector   // 将SEL数据转换为字符串
 NSSelectorFromString   // 将字符串转换为SEL数据

 不能使用[self performSelector:_cmd];会引发死循环

 发消息就是发送SEL

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值