Objective-C 学习笔记(1)——类与对象
2016-04-28 14:56
507 查看
一、Objective-C与C++的区别
Objective-C是一门面向对象的编程语言:它可以对类和对象进行管理;像在C++中一样,把头文件和实现文件分开写是非常有用的。OC使用.h作为头文件的后缀,使用.m作为实现文件的后缀。并且在OC中,使用 #import 包含头文件,而不是 #include。事实上,在c语言或者C++语言中,为了防止头文件被重复包含,需要使用头文件预处理防止头文件的重复包含。#import本身就有防止头文件被重复包含的功能。二、类的定义
接口部分(.h文件)
@interface className:parentClass <protocol,…> { //instanceVariable Declarations //实例变量的声明(相当于c++数据成员) } //method declarations //方法的声明(相当于c++成员函数) @end
ObjC定义了一个根类:NSObject。每一个新建的ObjC类都应该为NSObject的派生类。NSObject为运行时系统提供了大量的方法。
方法声明
mType (returnType) name1:(type1)param1 name2:(type2)param2... //方法类型(返回值类型) 方法名1:(参数1类型)参数名 方法名2:(参数2类型)参数2名称..
方法分为两种:类方法和实例方法 即方法中的方法类型mType分为两种:分别用 “+” 和 “-” 标识。
• 如果类型为 +,则表示方法类方法(相当于c++中的静态成员函数)
• 如果类型为 - ,则表示方法为实例方法(相当于c++中的非静态成员函数)
三、类的实现
实现部分(.h文件)
@implementation className//类代码实现的开始 Synthesized Property//@synthesize 指示符来为类的属性生成setter和getter函数的 methodDefinition//方法的实现 methodDefinition … @end//类代码编写的结束
OC中方法(函数)的规则:
所有的方法在 @interface…@end 部分声明,在 @implementation…@end 部分实现。如果一个或多个协议在interface部分列出,则协议中的相的方法可以在该类中实现。
方法实现
mType (returnType) name1:(type1)param1 name2:(type2)param2... { variableDeclarations//局部变量声明 programStatements//程序执行语句 … return expression;//返回一个定义的类型值 }
OC中方法实现(函数)的规则:
方法实现时,需要注意的是该方法原型必须和它在interface部分的声明保持一致;
实例方法可以通过名字引用本类或者本类中继承过来的实例变量,但是在类方法中,不可以引用实例变量;
在一个方法中,可以使用标识符 self 用作当前对象的引用,来调用当前对象的方法。类似于C++中的 this 指针。
四、消息机制
OC消息机制
消息机制:系统给对象发送消息,对象接受消息的一种方式。C++ 中函数的访问叫做对象调用函数;OC 中叫做向对象发送消息。对象收到消息做出响应(respond),接收消息的对象称为receiver,发送的消息称为selector 。• +方法:称为类方法(大致相当于C++中的静态成员函数) [类名 方法名]; eg. +(void)allNum; [Circle allNum]; • -方法:称为实例方法(C++中的非静态成员函数) [对象名 方法名]; eg. -(void)print; Circle circle; [circle print];
五、方法重载
在ObjC中方法的重载和C++中的重载不是一个形式;如果当我们使用重载时必须要注意,C++重载和OC的重载有不同的特性。前者是基于参数的类型,而后者是基于参数的标签。但是OC中没有严格意义上的方法重载。
OC里标签也可以匿名(即标签名称可以省略不写);
六、属性声明
自动生成get set 方法
所用关键字:@property及@synthesize,两者需要配对使用。具体如下:
• @property type name; (.h文件)告诉编译器:指定实例变量需要生成set()或get()方法
• @synthesize property_1,property_2, …;(.m文件)通知编译器自动生成set()或get()方法
属性设置会使编译器自动生成set/get方法,默认支持多线程。
nonatomic:该方法不需要多线程保护,节省开销。
调用get函数的两种方式
•方式1:对象名.实例变量; receiver.property •方式2:[对象名 实例变量名]; [receiver property];
调用set函数的两种方式
•方式1:对象名.实例变量 = 表达式; receiver.property = expression; •方式2:[对象名 属性设置函数 : 实例变量名]; [receiver setProperty: expression]; set后跟的实例变量名,其默认首字母要大写
属性声明的修饰类型
@property (属性参数1,属性参数2,...)类型 名字; 代码: @property (attributes) type name;
其中参数主要分为4类: • **数据读写访问属性**:readwrite(默认为读写)/readonly(只有get方法) • **内存设置属性**:assign (default), retain or copy • **多线程原子性属性**:atomic(default)/nonatomic(防止线程安全:非原子化操作,该方法不需要多线程保护,节省开销,提高程序性能) • **自定义设置访问方法名称属性**:getter=..., setter=... (用于改变默认名称) 参数意义: • **readwrite**:产生setter/getter方法; • **readonly**:只产生简单的getter方法,没有setter方法; • **assign**:默认类型,setter方法中适用于基本数据类型的实例变量直接赋值,而不进行引用计数加1操作; • **retain**:setter方法中会对实例变量旧空间释放(release),使得新旧两个指针变 量指向同一个对象(新对象),再进行retain操作,新空间引用计数再次加1; • **copy**:setter方法中会对实例变量旧空间释放(release),再对新对象进行copy 操作,赋值给旧对象(两个指针变量分别指向各自的对象,互不影响); • **atomic**:支持多线程,如果使用多线程,有时会出现两个线程相互等待对方导致“死锁”,使用atomic会防止出现此情况,但是会消耗指定的资源; • **nonatomic**:禁止多线程,提高性能; • **实例变量起别名**:在类外对类变量访问起保护作用(封装性); • **getter=访问方法名**:用户自定义访问变量的方法名; • **setter=设置方法名**:用户自定义设置变量的方法名;
七、类的组合
组合的概念
在ObjC中,你可以使用像C++中的类与类的关系来实现代码的复用,并提高程序的编写速率,即OC中类的组合关系。假设有一个圆,该圆由一个中心坐标点(x,y)和半径radius组合而成。你可以把这个点的(x,y)坐标单独用一个对象保存。或许你可以意识到,在开发的图形应用程序中,总会与许多坐标打交道,所以最好先定义一个点类表示这一类事物,取名为:XYPoint。然后再定义一个圆类取名为:Circle。二者关系如下:
Circle = XYPoint + radius;
即圆类由点类组合而成(这是一种 “has-a” 的关系)
• 先定义XYPoint类的接口
• 再定义Circle类的接口
/*** XYPoint.h ***/ #import <Foundation/Foundation.h> @interface XYPoint : NSObject { intx; inty; } @property int x, y; -(void) setX: (int) xVal andY: (int) yVal; @end /*** XYPoint.m ***/ #import "XYPoint.h" @implementation XYPoint @synthesize x, y; -(void) setX: (int) xVal andY: (int) yVal { x = xVal; y = yVal; } @end
/*** Circle.h ***/ @interface Circle : NSObject { int radius; XYPoint *origin; } @property int radius; @property XYPoint *origin; -(void)setOrigin:(XYPoint *) pt; -(XYPoint *) origin; -(int) area; -(int) perimeter; @end /*** Circle.m ***/ @implementation Circle @synthesize radius; @synthesize origin; -(void) setOrigin: (XYPoint *) pt //function name must be this { origin = pt;//形参pt为实例对象origin赋值 } -(XYPoint *) origin//to use .origin, this func must provide { return origin;//返回实例变量 } -(int) area { return radius*radius*3.14; } -(int) perimeter { return radius*3.14*2; } @end
为避免数据混乱和内存泄露的问题,对setOrigin函数做以下修改:
/*** Circle.m ***/ -(void) setOrigin: (XYPoint *) pt { if (origin){//如果原始对象存在 [origin release];//释放旧对象 } origin = [[XYPoint alloc] init]; //开辟新空间 [origin setX: pt.x andY: pt.y]; }
相关文章推荐
- git 错误 fatal: Not a valid object name: 'master'.
- java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 39 path $
- Object类
- 目标检测“Exploit All the Layers: Fast and Accurate CNN Object Detector with Scale Dependent Pooling and”
- potential leak of an object stored into xxx
- Object-c------多态
- 如何给List<Map<String, Object>> list 增加值和修改值
- Object-c------继承
- [乐意黎原创]php 抛Fatal error: Cannot use object of type stdClass as array in XXX的解决方法
- Xcode插件管理工具CocoaPods安装教程
- Objective-C中字符串NSString的常用操作方法总结
- [Angular 2] Using a Reducer to Change an Object's Property Inside an Array
- different object with the same identifier value was already associated with the session 问题解决
- Objective-C中的block代码块的使用
- 2.Samba安装问题:error while loading shared libraries: libXXX.so.X: cannot open shared object file
- Object-c------self
- ClassNotFoundException: com.fasterxml.jackson.databind.ObjectMapper的解决办法
- Object-c-----类方法
- 泛型与Object
- Foundation => Objective-C _ Part6