Objective-C笔记

简介:

1、在编译一个使用了CPerson类的文件时,如果不需要知道该类的全部细节,只需要知道有一个类名叫CPerson,最好“向前声明”该类(同理于对一个协议的引用),这样做也可以避免“循环引用”问题:

例:

@class  CPerson

例:

#import "CShape.h"

#import "CDrawable.h"

@interface  CRectangle : CShape <CDrawable>


2、多用字面量语法,少用与之等价的方法 (NSString/NSNumber/NSArray/NSDictionary)

字面量语法的限制:除了字符串以外,所创建出来的对象必须属于Foundation框架才行。如果自定义了这些类的之类,则无法用字面量语法创建其对象。

例:

NSString *someString = @"Effective Objective-C 2.0";

NSNumber *someNumber = @1 ;

NSNumber *floatNumber = @2.5f;

NSNumber *boolNumber = @YES;

NSNumber *charNumber = @'a';


NSArray *animals = @[@"cat", @"dog",@"pig"];//若@“dog”为空,程序会抛出异常令应用程序终止执行,达到检查是否含空字符串的目的

NSArray *dog = animals[1];


NSDictionary *personData = @{@"firstName" : @"Matt", @"lastName" : @"Galloway", @"age" : @28};//一旦有值为nil也会抛出异常

NSDictionary *firstName = personData[@"firstName"];


3、多用类型常量const static,少用#define预处理指令,这样创建出来的常量有类型信息,便于差错。

1)若不打算公开某个常量,则应将其定义在使用该常量的实现文件里;

2)在头文件中使用extern来声明全局常量,并在相关实现文件中定义其值。


4、用枚举表示状态、选项、状态码

enum Week {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};

enum Week day = Monday;


5、理解“属性” (属性用于封装对象中的数据,保存着数据的实例变量一般通过“存取方法”来访问)

1)atomic(原子性),如果属性具备nonatomic特质,则不使用同步锁;(开发iOS程序中所有的属性都声明为nonatomic,原因是:在iOS中使用同步锁的开销较大,这会带来性能问题;但是在开发Mac OS X程序时,使用atomic属性通常都不会有性能瓶颈。所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。)

2)readwrite(读写),拥有“获取方法”和“设置方法”,由@synthesize实现;

3)readonly(只读),仅拥有“获取方法”,由@synthesize实现;

4)assign,“设置方法”只会执行针对“纯量类型”(CGFloat、NSInteger等)的简单赋值操作,不更改索引计数,即setter方法直接赋值,不进行任何retain操作(对基础数据类型 (NSInteger)和C数据类型(int, float, double, char, 等)使用,否则可能导致内存泄露)

5)strong,设置方法会保留新值,并释放旧值,然后再将新值设置上去;使用ARC机制时,等同于retain

6)weak,设置方法既不保留新值,也不释放旧值。此特质同assign类似;使用ARC机制时,等同于assign,对象被释放时,属性的值会被设置为nil

7)copy,设置方法并不保留新值,而是将其“拷贝”,建立一个索引计数为1的对象,然后释放旧对象,即setter方法进行Copy操作,与retain处理流程一样,先旧值release,再Copy出新的对象,retainCount为1,为了减少对上下文的依赖而引入的机制(对NSString )

例:-(void)setOne:(NSObject *) other

{

if(one != other)

{

[one release];

one = [other copy];

}

}

8)retain,释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1,即setter方法对参数进行release旧值再retain新值,为了解决原类型与环循引用问题(对其他NSObject和其子类)

例:-(void)setOne:(NSObject *) other

{

if(one != other)

{

[one release];

one = [other retain];

}

}

(copy与retain的区别:

copy是创建一个新对象,retain是创建一个指针,引用对象计数加1

copy 到另外一个NSString 之后,地址为不同 ,内容相同,新的对象retain为1 ,旧有对象没有变化

retain 到另外一个NSString 之后,地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1)


a、property,他可以提供的功能有:提供成员变量的访问方法的声明、控制成员变量的访问权限、控制多线程时成员变量的访问环境

b、synthesize的理解是:实现property所声明的方法的定义

c、使用属性的话,编译器会自动生成存取方法,并自动向类中添加适当类型的实例变量,并在属性名前面加下划线。

d、可用@synthesize语法来指定实例变量的名字;用@dynamic关键字则会告诉编译器:不要自动创建实现属性所用的实例变量,也不要为其创建存取方法。


6、在对象内部尽量直接访问实例变量,在对象之外访问实例变量时总是通过属性来做 

(笔者强烈建议在读取实例变量的时候采用直接访问的形式,而在设置实例变量的时候通过属性来做)

(在初始化方法及dealloc方法中,总是应该直接通过实例变量来读写数据)

直接访问(_name) 与 属性访问(self.name) 的区别:

1)直接访问速度快,编译器所生成的代码会直接访问保存对象实例变量的那块内存;

2)直接访问不会调用“设置方法”,这就绕过了为相关属性所定义的“内存管理语义”;

3)直接访问实例变量不会触发“键值观测”(KVO)通知;

4)通过属性来访问有助于排查与之相关的错误,因为可以给“设置方法”设置断点。


7、理解“对象等同性”这一概念

1)按照 == 操作符比较的是两个指针本身,而不是其所指的对象;

2)应该使用NSObject协议中声明的“isEqual”:方法来判断两个对象的等同性。(“isEqualToString:”、“isEqualToArray:”、“isEqualToDictionary:”)

3)相同的对象必须具有相同的哈希码,但是两个哈希码相同的对象却未必相同。


8、instancetype和id的异同

1)相同点:

都可以作为方法的返回类型

2)不同点:

instancetype可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象;

instancetype只能作为返回值,不能像id那样作为参数。


9、@selector

1)一种类型 SEL

2)代表你要发送的消息(方法), 跟字符串有点像, 也可以互转.: NSSelectorFromString() / NSSelectorFromString()

3)可以理解为类似函数指针的东西–是能让Objective-C动态调用方法的玩意.–是 object-c 的动态后绑定技术 可以通过字符串 访问的函数指针

4)其实就是消息响应函数—选一个消息响应的函数地址给你的action

5)@selector(function_name) 即取得一个function的id


10、理解objc_msgSend的作用(“传递消息”)

1)消息由接收者、选择子(方法)及参数构成。给某对象“发送消息”也就是相当于在该对象上“调用方法”;

2)发给某对象的全部消息都要由“动态消息派发系统”来处理,该系统会查出对应的方法,并执行其代码;

3)C语言使用“静态绑定”(编译期就能决定运行时所应调用的函数),而objective-c则使用“动态绑定”(所要调用的函数直到运行期才能确定)

4)编译器看到消息后,会将其转换为一条标准的C语言函数调用,这个核心函数叫做:objc_msgSend:

id returnValue = [someObject messageName:parameter];

==> id returnValue = objc_msgSend(someObject, @selector(messageName:), parameter);

(该方法需要在接收者所属的类中搜寻其“方法列表”,如果能找到与选择子名称相符的方法,就跳至其实现代码。若是找不到,那就沿着继承体系继续向上查找,等找到合适的方法之后再跳转。如果最终还是找不到相符的方法,那就执行“消息转发”操作。)


11、@synthesize和 @dynamic

@property有两个对应的词,一个是@synthesize,一个是@dynamic。如果@synthesize和@dynamic都没写,那么默认的就是@syntheszie var = _var;

@synthesize的语义是如果你没有手动实现setter方法和getter方法,那么编译器会自动为你加上这两个方法。

@dynamic诉编译器,属性的settergetter方法由用自己实现,不自生成。(当然对于readonly的属性只需提供getter即可)。假如一个属性被声明为@dynamic var,然后你没有提供@setter方法和@getter方法,编译的时候没问题,但是当程序运行到instance.var =someVar,由于缺setter方法会导致程序崩溃;或者当运行到 someVar = var时,由于缺getter方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。

12、全局变量,和局部变量再内存占用上有什么区别?

变量可以分为:全局变量、静态全局变量、静态局部变量和局部变量。  按存储区域分,全局变量、静态全局变量和静态局部变量都存放在内存的静态存储区域,局部变量存放在内存的栈区。  

按作用域分,全局变量在整个工程文件内都有效;静态全局变量只在定义它的文件内有效;静态局部变量只在定义它的函数内有效,只是程序仅分配一次内存,函数返回后,该变量不会消失;局部变量在定义它的函数内有效,但是函数返回后失效。  

全局变量和静态变量如果没有手工初始化,则由编译器初始化为0。局部变量的值不可知。  

静态全局变量,只本文件可以用。  

全局变量是没有定义存储类型的外部变量,其作用域是从定义点到程序结束.省略了存储类型符,系统将默认为是自动型.  

静态全局变量是定义存储类型为静态型的外部变量,其作用域是从定义点到程序结束,所不同的是存储类型决定了存储地点,静态型变量是存放在内存的数据区中的,它们在程序开始运行前就分配了固定的字节,在程序运行过程中被分配的字节大小是不改变的.只有程序运行结束后,才释放所占用的内存.  

自动型变量存放在堆栈区中.堆栈区也是内存中一部分,该部分内存在程序运行中是重复使用的.       

目录
相关文章
|
JavaScript C++ iOS开发
Objective-C 入门笔记
简介 建立在C语言之上,可以混编C/C++代码,编写一个类需要二个文件: .h的头文件 .m的实现文件(如果是C/C++混编文件,文件后缀为.mm) 既然有头文件,所以很多人会拿它与C++进行类比,它最重要的三个特性是:Message、Category、Protocol,与C++类比,二者之...
950 0
|
API iOS开发 Swift
【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记9 Objective-c Compatibility
我们都知道在Swift诞生之前进行IOS开发一直使用Objective-c这门语言。OC和Swift之间需要一个桥接。
873 0
|
iOS开发 索引 编译器
【《Objective-C基础教程 》笔记】(七)OC的关键字用意小结
1.  #import     #import 从system目录中查找头文件,不会检查当前目录。     #import "" 首先在当前目录中查找,如果未找到,则在Xcode设置的预处理程序搜索路径中查找文件。
768 0
|
存储 iOS开发
【《Objective-C基础教程 》笔记】(八)OC的基本事实和OC杂七杂八的疑问
一、疑问 1、成员变量、实例变量、局部变量的区别和联系,在访问、继承上如何表现。 2、属性@property 和 {变量列表} 是否相同,有什么不同。 3、类方法、类成员、类属性;实例方法、实例变量、实例属性。
903 0
|
iOS开发
【《Objective-C基础教程 》笔记ch05】(六)OC中的复合机制Composition
 1、复合通过包含作为实例变量的的对象指针实现的。        @interface Unicycle : NSObject        {           Pedal*pedal;           Tire*tire;         }//Pedal和tire通过复合的方式组成了Unicycle 2、存取方法——用来读取或者改变某个对象属性的方法。
1018 0
|
iOS开发 调度 编译器
【《Objective-C基础教程 》笔记ch04】(五)OC中的继承inheritance机制
一、为什么需要继承                            使用继承一方面继承了父类的特性,另一方便解决了重复代码维护问题。 二、继承之语法          1、 @interface 子类名:父类名          2、 OC只支持单继承,不支持继承多个父类。
911 0
|
C语言 C++ iOS开发
【《Objective-C基础教程 》笔记ch02】(一)Hello Object-C 项目
一、项目实现步骤。 1、若xcode尚未运行,先启动它。 2、选择Select File --> New --> New Project菜单选项。 3、选择左边OS X下得application,再选中右边的command line tool,点击next。
1028 0
|
iOS开发
【《Objective-C基础教程 》笔记ch02】(二)Boolean类型及实例
一、布尔类型         布尔类型是一种对带符号的字符类型(signed char)的类型定义,使用8位的存储空间。         通过#define指令把YES定义为1,NO定义为0,都是8位的二进制数。
1021 0