目录:
Objective-C简介
1980年代初,Brad Cox发明了Objective-C;
1985年乔布斯成立了NeXT公司,创建了NextSTEP,使用Objective-C开发的用户界面工具包;
1996年,苹果公司收购NeXT公司,NextSTEP被重新命名为Cocoa,应用在了Macintosh编程上;
2007年,iPhone发布,Objective-C又是iOS平台软件开发的语言,直到2010年,iphone4的推出,将苹果公司置于科技界顶峰,Objective –C也越来越多的人学习;
Objective-C是C语言的扩展集
封闭的编程语言
动态语言
拓展延伸
动态性:
三个方面:动态类型,动态绑定,动态加载
动态类型:静态类型(int,nsstring)这种明确的类型,静态在编译的时候就能识别,若程序发生类型不对应,编译器就会报错,所以动态类型(id)程序在编译的时候不会识别,只有在运行的时候才会识别
动态绑定:(dynamic)但事实上很简单,只需记住关键词@selector/SEL即可,在oc中没有函数的概念,我们叫消息机制,所谓的函数调用就是给对象发送一条消息,oc可以跳过编译,到运行时才决定调用什么方法,需要什么参数,要实现动态绑定,必须用SEL绑定一个方法。
之所以叫动态,是因为必须在运行时 (runtime)才会做的一些事情
动态载入:让程序在运行时添加代码模块以及其他资源。用户可以根据需要加载一些可执行代码和资源,而不是在启动时就加载所有组件。可执行代码中可以含有和程序运行时整合的新类。
对象是运行时类的一个实例。在类里声明了的实例变量和方法,它的每个实例都在内存中拥有同样的实例变量,以及指向那些方法的指针。在oc中对象永远是通过指针来引用的。
比较Objective-C与C的不同点
举例:
> 去饭店吃饭,你只要说明吃什么就可以了,有必要还了解这个菜是怎么做的,是哪里来的,怎么去种这个菜吗?
>
> 面向对象也可以说是从宏观方面思考问题,而面向过程可以说是从细节处思考问题。
>
>
>
> 举个例子,盖一座大楼,你想到的是楼怎么盖,哪里要有柱子,哪里要有梁,哪里楼梯等等(这就是面向对象),至于柱子该怎么建,用什么建,方的圆的,等等,这就是面向过程。
>
> 用面向对象思考问题更符合我们人的思考方式。 其实我们人现实生活中都是在面向对象
C语言:面向过程,侧重于于事件的每一个步骤
OC语言:面向对象,侧重于达到目标的方式和结果
HelloWorld解析
现在我们创建一个oc工程文件,和c文件的创建过程一样,只需将language改为oc.
#import
int main(int argc, const char * argv[])
{
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
}
return 0;
}
1.oc的文件名:main.m注意后缀是.m文件
2.代码:头文件 #import
3. #import:防止重复引用
#include:多次重复编译
@class 声明一个类,告诉编译器这个他后面的名字是一个类,关于这个类的定义实现我们暂时不用知道
<>:导入的是系统的库
“”:导入的时自定义的一些文件
4. @autoreleasepool 这个是自动释放池用于内存管理,后面会讲
5. nslog和printf一样,用来打印信息,但他们区别“
1.NSLog会自己加上换行符
2.NSLog在Debug下会写到system.log(日志信息)中
3.NSLog会自动加上时间和进程信息
4.NSLog支持%@去打印一个对象类型
@:
* 1、作为OC关键字的起始
* 2、使用%@可自动调用description方法对该对象进行描述,即打印对象信息
* 3、在iOS5之后,对部分数据类型的简写 比如:@(1) @"" @[] @{}等
* 等
类和对象
刚我们说用%@打印对象,那什么是对象,那你首先要了解什么是类。
类(class):对一类事物抽象的描述(抽象)
对象(object):从一类事物中具体化出来的一个实例(具体)
创建类的三种方式:
1.可以菜单栏file--new--file
2.选中工程文件,右键newfile
3.command + n
分析类
创建一个人类,命名Human
其文件分为2部分:
.h文件为类的声明文件,关键字@interface用来表示类的接口。
.m文件为类的实现文件,关键字@implementation用来表示类的实现。
接口和实现都必须使用@end结束,即:@interface @end 和@implementation @end 成对出现。
Human.h
全局变量
在类的声明中添加的,可以在这个类中使用的变量。
某种意义上,类似于结构体的成员变量。
给Person类增加几个全局变量:
#import
//接口 类名 :父类名
@interface Human : NSObject
{
//成员变量(实例变量,全局变量)
NSString *_name;//姓名,为了区分参数名名称,通常成员变量带下划线
NSInteger _age;//年龄,通常OC中不使用int,使用NSInteger
}
//注意上例中,name和sex的类型都是NSString *,因为他们需要用OC字符串对象来描述,而age的类型是NSInteger,不需要*,因为它只需要用数值来描述即可。
@end
Human.m
#import “Person.h”
@implementation Person
@end
/**
* 成员变量的作用范围:
@public:在任何地方都能直接访问对象的成员变量
@private:只能在当前类的对象方法中直接访问,如果子类要访问需要调用父类的get/set方法
@protected:可以在当前类及其子类对象方法中直接访问(系统默认下是用它来修饰的)
@package:在同一个包下就可以直接访问,比如说在同一个框架
注意:
无论父类是在@interface还是@implementation声明的成员变量子类都能拥有;但是子类能不能直接通过变量名来访问父类中定义的成员变量是需要看父类中定义的成员变量是由什么修饰符来修饰的。
默认:在@implementation中成员变量的修饰符为@private,
在@interface中成员变量的修饰符@protected
*/
NSObject简介
OC语言只支持单继承,一个子类只有一个父类,多继承可以使用类别及协议;
NSObject是所有类的根类,任意OC的类都源于NSObject;
NSObject 可以简写为id,同时id也可以代表所有对象类型(类似void 泛型指针);
所有子类都可以使用父类的方法,所有对象都能使用NSObject类的方法;
使用%@可以打印任意对象的信息;
对象本质上都是指针,可以直接通过 == 或 != 判定2个对象是否是同一个。
建立对象
有了类,那我们到底怎么用呢,那就需要对象了。
//创建对象的步骤:
在main函数中建立一个Person对象:
第一步,导入类:
第二步,分配内存初始化:
第三步,使用临时变量接收其返回值:
Human *per = [Human alloc] init];
//课分成两步写:
//分配内存
Human *human1 = [Human alloc];
//初始化
human1 = [human1 init];
通过上面的步骤,最后得到的per就是我们想要的一个Person对象。
初始化方法
NSObject类有init方法,可以直接使用其init,但大多数情况下我们都需要重写init
Human.m
@implementation Human
/*
OC语言是单根继承,在一个类初始化之前,实际上是先初始化其父类,赋值给self,然后再添加自身的特性,最后返回self。
*/
- (instancetype)init{
self = [super init];
if (self) {
//OC中对变量赋值的方法和C类似,当试着给变量赋值时,如果直接赋值常量,可以直接使用如下方法:
_age = 12;
_name = @"lili";
}
return self;
}
@end
main.m
Human *human1 = [[Human alloc] init];
//在没有重写init方法之前,它默认走系统默认的
- (instancetype)init;方法
//一旦我们重写了init方法,他就不会走系统的了,他会走我们重写的init方法去初始化对象
自定义初始化方法
Human.h
#import
@interface Human : NSObject
//接口部分,公开的
- (instancetype)initWithAge:(NSInteger)age name:(NSString *)name;
- (void)introduce;
@end
Human.m
- (instancetype)initWithAge:(NSInteger)age name:(NSString *)name{
self = [super init];
if (self) {
_name = name;
_age = age;
}
return self;
}
- (void)introduce{
NSLog(@"我叫:%@,我的年龄:%ld",_name,_age);
}
main.m
Human *human2 = [[Human alloc] initWithAge:15 name:@"kimi"];
[human2 introduce];//对象可以调用在.h的方法,写在接口文件的方法外部是可以访问的
很多同学学完这个初始化方法后都会很疑惑为什么要学两种,到底用哪一种?这相当于选择题,我们在创建对象的时候必须要有初始化这一步,那初始化总的来说就有三种:系统的,重写init,自定义init。
总结:系统的init方法,仅仅只是让你的对象存在,并没有赋值这些。
但往往很多时候我们在初始化一个对象让他存在的同时,我们想让他带有一些信息,这时候,系统的就满足不了我们,我们就可以通过重写init方法来实现初始化并赋值。
当然除了重写init,我们还可以自定义初始化方法,它的好处就是可以在外部通过传参赋值,基本上和重写效果一样。
如何选用:就看你想在外部通过传参赋值,还是直接重写init直接赋值。
这个只需要大家多用就不会有什么问题了!