#import功能与include基本相同,不过它避免了重复引用的问题(class A,class B都引用了class C,class D若引用class A与class B,就会报重复引用的错误)。所以在OC中我们基本用的都是import。
#import<>用于对系统文件的引用,编译器会在系统文件目录下去查找该文件。
#import"xx.h"用于对用户自定义的文件的引用,编译器首先会去用户目录下查找,然后去安装目录,最后去系统目录查找。
@class就是告诉编译器有这个类存在,但是类是如何实现的不用告诉编译器.若.m文件用到了这个类,还是要在.m文件汇总import这个类的。
既然这样,为什么不直接在头文件中import呢,举个例子:
class A引用了class B,class B引用了class C.... , class A,B,C...的头文件又import了很多文件,那么 import了A的话,编译器就需要编译大量的文件,编译时间就会增加。
难道头文件中都是用@class吗?当然不是,有时也是需要#import的,那么什么时候该用什么呢?
(1)一般如果有继承关系的用#import,如B是A的子类那么在B中声明A时用#import;
(2) 另外就是如果有循环依赖关系,如:A->B,B->A这样相互依赖时,如果在两个文件的头文件中用#import分别声明对方,那么就会出现头文件循环利用的错误,这时在头文件中用@class声明就不会出错;
(3)还有就是自定义代理的时候,如果在头文件中想声明代理的话如@interface SecondViewController:UIViewController
时应用#import不然的话会出错误,注意XXXDelegate是自定义的。
2. Objective-C的内存管理方式, NSAutoreleasePool的作用?
NSAutoreleasePool是用于管理iphone应用的生命周期内所有的自动释放对象。当应用程序中有自动对象创建时,该对象就会被加入到该自动释放池。当应用程序结束时,该池会释放池中全部的自动释放对象[pool release];
在 Objective-C中每个对象都对应着他们自己的持有计数(Retain Count),持有计数可以理解为一个整数计数器,当使用alloc方法创建对象的时候,持有计数会自动设置为1。当你向一个对象发送retain消息 时,持有计数数值会增加。相反,当你像一个对象发送release消息时,持有计数数值会减小。当对象的持有计数变为0的时候,对象会释放自己所占用的内存。
3. 为什么很多内置类如UITableViewController的delegate属性都是assign而不是retain?
如果是retain会引起循环引用。所有的引用计数系统,都存在循环引用的问题。例如下面的引用关系:
对象A创建并引用了对象B
对象B创建并引用了对象C
对象C创建并引用了对象B
这时候B和C的引用计数分别为2和1.当A不再使用B,调用release释放对B的所有权,因为C还引用了B,所以B的引用计数为1,B不会释放。B不释放,C的引用计数就是1,C也不会被释放。从此,B和C永远留在内存中。这种情况,必须打断循环引用,通过其他规则来维护引用关系。比如,我们常见的delegate往往是assign方式的属性而不是retain方式的属性,赋值不会增加引用计数,就是为了防止delegation两段产生不必要的循环引用。如果一个UITableViewController对象A通过retain方式获取了了UITableView对象B的所有权,这个UITableView对象B的delegate又是对象A,如果这个delegate也是retain方式的,那么基本上就没有机会释放这两个对象了。我们自己在设计使用代理模式的时候,也需要注意这一点。
4. 用objective-c写冒泡排序
-(NSArray *)bubbleSort:(NSArray *) array
{
for(int i=0; i<[array count]; i++)
{
for(int j=i+1; j<[array count]; j++)
{
int a = [[array objectAtIndex:i] intValue];
int b = [[array objectAtIndex:j] intValue];
if(a>b)
{
[array repalceObjectAtIndex:i withObject:[NSString stringWithFormat:@'%d',b]];
[array repalceObjectAtIndex:j withObject:[NSString stringWithFormat:@'%d',a]];
}
}
}
return array;
}
5. 用预处理指令#define声明一个常数,用来表示1年中有多少秒(忽略闰年)
#define SECONDS_PER_YEAR (365*24*60*60)UL
另写一个标准宏MIN,这个宏输入两个参数并返回其中较小的一个:
#define MIN(A,B) ((A)<=(B)?(A):(B))
#define语法基本知识:不能以分号结尾,注意括号的使用。