从上星期四开始自学OC到现在刚好一个星期,因为有C语言的基础,所以学得还算比较快。至今学习总结的都是比较浅层的东西,但希望能把自己学到的东西用博客的方式记录下来,一来可以帮助自己复习总结,而来可以和很多CSDN的高手互动交流。
这星期开始会陆续写三篇自己自学OC的总结,这是第一篇——OC基础入门篇
OC并不是一种独立的语言,其实他是以C语言为基础的面向对象的语言(不得不说C的庞大和优越)所以他是兼容C语言的。比较特别的OC关键字都是以@开头,比如:@class、@interface、@implementation、@public、@private、@protected等等。OC中所有的函数都是虚函数,这一点也与C不一样。
下面先看一段代码:
//Cat.h
#import<Foundation/Foundation.h> // 在这里#import就相当于C语言中的#include, 而Foundation.h就是函数库
@interface CAT :NSObjce{
(int) num;
}
-(void)saySomething
-(void)setNumber
@end
上面我们建立了一个CAT类,定义了一个变量num来记录每一只猫的号码。大家会发现:
-(void)setCat这个方法(message)前面有个“-”的符号,其实他表示这个方法是一个实例方法,
如果前面是“+”,则表示这是一个类方法,可以脱离实体运行,而括号里面的就是这个方法的返回值类型。
下面来总结一下关于类的声明方法:
@interface +类的名字:父类的名字
{
实体变量类型 + 实体变量名;
}
—(返回值类型)方法名字:(变量类型)变量名;
+(返回值类型)方法名字;
@end
然后在项目游览器选择“Cat.m”文件,进行类的定义
#import“Cat.h”
@implementation Cat // @implementation—@end之间表示类的定义,Cattle是类的名字,下面就是一些方法的定义
(void)saySomething
{
NSLog(@”Hello,I am a cat , My Number is %d,num);
}
(void)setNum : (int)Number
{
num=number;
}
@end
做完类的声明与定义我们回到打开主文件会看到:
#import<Foundation/Foundation.h>
#import"Cat.h"
Intmain(intargc,constchar*argv[])
{
NSAutoreleasePool*pool=[[NSAutoreleasePoolalloc]init];
[pooldrain];
return 0;
}
在OC里面我们会经常遇见NS这两个字母,其实NS只是一个前缀。
程序运行的时候需要向系统申请内存空间,而 Autorelease就是一种利用线程管理内存的方式,本质上是一种延迟释放内存的机制。
说到内存管理就一定要说说计数器,每个OC的对象都会有一个计数器,用来记录当前被引用的次数,关于计数器:从一段内存被申请之后就会存在一个变量用来计算这段内存被使用的次数,当它为0的时候内存将被释放。而pool就是所有计数器的集合。
OC对内存管理是很严格的,如我们对一个对象使用了alloc、[mutable]copy、retain,就必须使用相应的release或者autorelease,但其实在新版里我们不必严格去管理,因为系统会自动帮我们去扫描检验了。
补充1:
Object-C 分类(Category)拓展(Extension)协议(Protocol)
分类(Category)
1、作用:分类是为现有类添加新方法的一种方式
2、Category的局限性:
1)Category无法向已有类添加实例变量,也就是只能用已有类原有的实例变量是写新方法;
2)若Category的新方法与已有类的方法名冲突,Category的方法优先级较高,因此最好将方法名区分开来。
3、实例:
比如说我要给我的Cow类添加一个分类,分类中实现了一个新的方法:计算Cow的个数:
点击newFile,选择Object-C File
选择Category即可,代码:
<span style="font-size:18px;">#import "Cow.h"
@interface Cow (CowNumber)
+(int)calculateCow;
@end
@implementation Cow (CowNumber)
+(int)calculateCow{
//
int cowNumber;
return cowNumber;
}
@end</span>
Category利用Object-C的动态特性,即使不知道某个类的具体代码也可以往里面塞新的方法,非常灵活。
拓展(Extension)
1、可以把拓展理解为是一种匿名的Category,但是跟Category不同的是Extension可以添加实例变量
实例:
这里有两种方式实现Extension,一种是按照上面Category的过程选择Extension,这时候会生成一个.h文件
在里面进行原有类的拓展。
然后在cow这个类中包含这个文件即可,如:#import "Cow_CowLeg.h"。
这时Cow中就可以使用拓展的新的实例变量Value以及新的方法。
但是在xode4之后就推荐在自定义类.m文件中使用拓展,实现良好的代码封装,避免将私有接口暴露,如:
<span style="font-size:18px;">#import <Foundation/Foundation.h>
@interface Cow : NSObject
@end
@interface Cow ()//注意:此处为扩展
{
float value;
}
-(void)setvalue:(float)newValue;
@end
@implementation Cow
-(void)setvalue:(float)newValue{
value = newValue;
}
@end</span><span style="font-size: 18px;">
</span>
在Object-C中,Protocol被用来定义一组独立于具体类的属性和方法,其不具体实现这些方法,任何类都可以实现Protocol,Protocol可以继承另一个Protocol,从特征上看Protocol的作用类似于Java世界的接口。
Protocol在具体的使用过程中基本上采用了“Delegation”模式,即采用Protocol定义方法,然后不同的类使用不同的具体实现,从而完成某个行为的多态。 在iOS的SDK类库中大量使用了这样的Delegate的模式,比方说UITableViewDataSource定义了Table View如何使用数据源的一系列方法,开发者需要使用Table View时,就需要实现这一系列方法,然后把自己定义的Table View delegate给当前对象。这样,不同界面的Table View就可以基于自身对象的实现做不同的展现。
定义protocol非常简单,如下:
- @protocol MyProtocol <NSObject>
- // list of methods and properties
- @end
除此之外,protocol定义时,还支持2个关键字,@required和@optional。顾名思义:凡是在@required后面的方法,实现该protocol的类必须实现,optional后面的方法可以不实现。默认所有的方法和属性都是@required的。
- @protocol MyProtocol <NSObject>
- // list of methods and properties
- @required
- // list of methods and properties
- @optional
- // list of methods and properties
- @end
另外,protocol还可以继承另一个protocol。
- @protocol A
- -(void)methodA;
- @end
- @protocol B <A>
- -(void)methodB;
- @end
实现protocol也非常简单, 在Object-C中,一个类要使用某个protocol,只需要在类定义时加上‘<ProtocolName,...>’就行了。
- @interface MyClass : NSObject <MyProtocol, AnotherProtocol, YetAnotherProtocol>
- ...
- @end
最后,和Java中的接口一样,一旦某个对象实现了某个protocol, 那么就可以用该protocol的指针来指向该对象。这就是为什么当当前对象实现了UITableViewDataSource protocol,就可以把Table View的delegate赋值给当前对象。 在UITableView的代码中,dataSource属性的定义是这个样子的。
- ...
- id <UITableViewDataSource> _dataSource;
- …
贴上该网友对Protocol介绍的链接:点击打开链接 谢谢该网友!