在IOS的学习中,估计很多开发人员容易上手,但真正内部结构,我想理解起来也是比较费劲,因为IOS开发并不是一门开源语言,语言的基础架构,有一些部分不凡多做些猜想验证,并通过苹果官方文档求证,接下来按自己的理解将OC基础语言的3个陷阱进行讲解;
1. MRC模式,NSString进行retainCount的值:
根据苹果的官方文档上面写着应该返回的是这个对象的UINTMAX_MAX, 并且不会释放,这个UINTMAX_MAX是最大十六进制(0xffffffffffffffff)
如果你当成有符号数取补码后输出就得-1;
如果你当成无符号数就是最大数即:18446744073709551615
这是因为字符串产生的对象是属于autorelease pool,在帮助文档中可以看到这么一句话:
The retainCount method does not account for any pending autorelease messages send to the receiver.
就是说retainCount对于autorelease消息产生的的对象,并不可靠。
Do not use this method. (required) You should never use-retainCount, because it never tells you anything useful.
永远不要用这个方法,只要遵守alloc,retain或copy以及任何需要分配内存的时候调用release就可以了
2. Property中的strong与weak
在ARC模式下有两种Property的属性参数用于修饰自定义对象,strong和weak;这两个参数的用法如下:
strong :强引用,指针对对象具有决定的占有
weak : 弱引用,指针对对象不具有决定的占有
这两个属性参数的用法,通常是在开发中不容易理解一个问题,举个生活中的实例:
如果有5个人都牵着这一条狗(5条绳子栓一只狗) ,相当于 5个strong类型指针指向一个对象。
除非5个绳子都脱落(也就是5个strong指针都=nil,则该对象释放),否则狗是不会跑掉的;
weak型指针就像是一个小孩子指着狗喊道:“看,有一只狗在那里”,只要狗一直被拴着,那么小孩子就能看到狗(weak指针)会一直指向它,只要狗的绳子脱落,那么狗就会跑掉,不管有多少的小孩在看着它。
在使用场合中,一般情况下,我们都使用strong;特殊情况如,在协议代理与IBOutlet控件的映射,我们使用weak属性参数作修饰;因为IBOutlet的属性为weak,是因为它已经被view引用了,除非view被释放,否则IBOutlet的属性也不会被释放,另外IBOutlet属性的生命周期和view应该是一致的,所以IBOutlet属性一般设为weak。
参考官方文档如下: From a practical perspective, in iOS and OS X outlets should be defined as declared properties. Outlets should generally be weak, except for those from File’s Owner to top-level objects in a nib file (or, in iOS, a storyboard scene) which should be strong. Outlets that you create will therefore typically be weak by default, because: Outlets that you create to, for example, subviews of a view controller’s view or a window controller’s window, are arbitrary references between objects that do not imply ownership.
The strong outlets are frequently specified by framework classes (for example, UIViewController’s view outlet, or NSWindowController’s window outlet)。
简单的说,如果IBOutlet对象是nib/sb scene的拥有者(File’s owner)所持有的对象,那么很显然拥有者必须“拥有”对象的指针,因此属性应设置为strong。而其他的
IBOutlet对象的属性需要设置为weak,因为拥有者并不需要“拥有”他们的指针。举例来说,UIViewController的view属性是strong,因为controller要直接拥有view。而添加到view上的subviews,作为IBOutlet只需要设置为weak就可以了,因为他们不是controller直接拥有的。直接拥有subviews的是controller的view,
3.自定义对象拷贝的过程
在ARC模式中,使用自定义的对象进行copy,我们知道会出现程序奔溃,关于奔溃的原因,我们可通过字符串的copy进行分析;使用字符串对象进行copy系统不会出现奔溃;且字符串中与自定义对象所在类一样,并没有copy的方法,由此可知,都是调用的是父类NSObject的的copy,由此产生了疑问:
疑问:NSString与自定义对象都是调NSObject的方法,要报错的话NSString也同样会报错
分析1:NSString类遵守了NSCopying协议:从而可知,NSString中一定实现了协议中必须的方法:copyWithZone
分析2: 我们可做一个猜想,字符串调用copy方法,必定内部调用了copyWithZone,字符串中有这个copyWithZone的实现方法所以不会奔溃;然而,自定义类因为没有实现协议方法,所以copy方法的实现部分调用copyWithZone会导致奔溃;
分析3: 通过验证法求证,自定义对象调用copy方法,内部也会调用了copyWithZone;用自定义类遵守NSCopying,然后实现copyWithZone的方法;
结论:在完成分析3的操作后,执行程序并没有出现程序奔溃;证明我们进行的推论正确,实质自定义代理对象的拷贝过程是通过协议代理完成;在以后我们学习的过程中,经常会碰到类似的通过协议代理暴露更多接口的设计模式,包括自定义的协议代理与系统提供的协议代理:
a.自定义的协议代理有完成的操作步骤: (1) 定制一张协议,在协议中声明协议方法
(2) 被代理者:声明委托代理对象;指派委托代理对象去调用代理协议方法
(3) 代理者:遵守协议;实现协议方法;设置代理对象(将代理对象传入被代理者声明的委托代理对象中)
b.系统统提供的协议代理分为两个部分:(以自定义拷贝对象为例) 第一部分:系统已生成的部分: (1)。 系统定制协议:NSCopying (2)。 被代理者:NSObject 第二部分:开发者需完成的部分
(3)。 代理者:遵守协议,实现协议方法,(隐含设置代理)
C语言和OC和C++的区别
答:c语言是面向过程的,OC是面向对象的,OC是基于C之上的扩展。OC的工作原理,系统发送消息给对象,让对象按消息内容工作。它用的是消息机制(Smalltallk-style)。 Mac OS X(桌面式电脑操作系统)iOS(移动设备操作系统)是苹果的两大操作系统 main.m m:是message的意思。
@autoreleasepool{ } //自动释放池 分析:@ :表示一个对象,表示字符的值。 注意:在OC中把类声明的指针称为对象。 #import 《Foundation/Foundation.h》
#inport:文件包含,自动防止重复包含。Import:是导入的意思。 nil :相当C++中NULL;
NSAutoreleasePool* pool = [NSAutoreleasePool alloc]; [pool init];
[pool drain];//倾倒
分析:这三句相当自动释放池。[pool drain ]:给pool对象发出drain消息,中括号表示消息机制,消息由系统发送,pool接收。alloc:给对象分配空间,并给成员变量初始化为0,init :初始化对象,类似于构造函数OC创建一个对象。 5、gcc – framework Foundaton files –o prongame 。/program ————编译一个源程序文件
分析:framework是框架的意思,-o :是给文件起一个别名,prongame:在这里是别名,这样生成的可执行文件,。/program 即可执行
评论
查看更多