[Objective-C] 2014.11.28

来源:互联网 发布:歧视 知乎 编辑:程序博客网 时间:2024/05/22 17:08
 1.1.1内存的创建与释放

    id testObject = [[ClassName alloc] init];
    alloc是Objecive-C中常用来申请内存块的方式。
此时,对于对象"testObject"来说,它的引用计数就是1了,原因是它调用了alloc来创建了一块属于自己的内存,这样
对象的引用计数+1,另外,Object_C中的另两个关键字retain和copy也会将对象的引用计数+1,。

根据内存管理机制,在使用完"testObject"后需要释放它。

    [testObject release];
流程:
alloc->retain->release->release。
release后的对象,虽然已经释放,但是它的指针地址仍然存在,只是指向了一块已经释放且无用的内存。所以无论从
安全释放的角度还是编码习惯上,都建议在release后直接赋个nil来置空。

    [testObject release];
    testObject=nil;
这样做仍然不算安全,试想在对testObject释放时,我们并不知道testObject的引用计数是否已经是0了。
如果对象引用计数已经是0,则会造成双重释放的问题。那么我们需要在释放的代码之前插入一段判断语句,即:

    if(!testObject){
        [testObject release];
        testObject=nil;
    }
对每个对象都写上三行释放代码实在是过于麻烦,于是有了释放对象的宏!即:

    #define RELEASE(obj) if(obj){[obj release]; obj=nil;}
//一般,如果我们知道需要实现功能所涉及的Class Name的具体类名,就不建议是使用init去初始化
 1.1.2自动释放池和使用
所有运行在苹果run time环境的程序,都会在程序的主消息循环的自动释放池里面运作,也就是在main()
函数中营造的那个自动释放池的闭包中,示例代码如下:

    int main{
        //自动释放池
        NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
        int retVal = UIApplicationMain(argc,argv,nil,nil);
        [pool release];
        return retVal;
    }
1.1.3
   说到自动释放池,就不得不提实例方法和类方法,那么什么是实例方法,什么是类方法呢?
实例方法:就是得有了具体实例(对象)后才能使用的方法,一般以"-"号形式作为方法的前缀来声明,比如API定义。

    -(id)initWithString:(NSString *)astring

应用例子:
    
    NSString*strTest=[[NSString alloc] initWithString:@"I'm an instance method!"];
    //其中"initWithString",只能被具体的对象调用,例子中的,[NSString alloc]当场返回一个指向NSString对象的指针。

相比而言,“类方法”则无须具体对象,只需要类的名称即可调用,一般以加号的形式作为方法的前缀来声明,比如API定义。
    
    +(id)stringWithString:(NSString *)aString
应用例子:

    NSString *strTest[NSString stringWithString:@"I'm an class method"];
其中"stringWithString"会为"strTest"对象创建一块内存,需要注意的是,这块内存一般已经被加入到“自动释放池”中去了,因此类对象
创建出来的对象,无需手动释放。



0 0
原创粉丝点击