现在的位置: 首页 > 综合 > 正文

Object-C 学习笔记(五)—构造方法

2013年03月03日 ⁄ 综合 ⁄ 共 2512字 ⁄ 字号 评论关闭

说到构造方法,我很想吐槽,Object-C是一种面相对象的语言,但是感觉OC自立门户,思想一致,语法奇葩.

(1) 由C语言发展而来,却抛弃了世界统一的写法.

(2)大家都知道C++是既面向过程,也面向对象,但是新版的C++都完全面相对象,封装程度跟java和C#差不多,但是Object-C居然比C++封装程度还低.

今天发现,OC连构造方法都要自定义

例子:

//
//  People.h
//  Constructor
//  DRAGON
//  Created by 5016 on 13-12-2.
//  Copyright (c) 2013年 dradon. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface People : NSObject

//属性声明
//引用型使用retain,基本数据类型使用:assign
//nonatomic 非原子性操作(引起线程安全问题);atomic 原子性操作
@property(retain,nonatomic)NSString *name;
@property(assign,nonatomic)NSInteger age;
@property(retain,nonatomic)NSString *school;

//构造方法自定义
-(People *)initWithName:(NSString*) name
                 andAge:(NSInteger) age
              andSchool:(NSString*) school;

+(People *)PeopleWithName:(NSString*) name
                   andAge:(NSInteger) age
                andSchool:(NSString*) school;
//无参构造方法
+(People *)_People;

@end

//
//  People.m
//  Constructor
//  DRAGON
//  Created by 5016 on 13-12-2.
//  Copyright (c) 2013年 dradon. All rights reserved.
//

#import "People.h"

@implementation People

//使用属性定义,自动生成getter和setter
@synthesize name = _name;
@synthesize age = _age;
@synthesize school = _school;

//自定义无参构造方法
+(People *)_People
{
    People* person = [[People alloc] init];
    return [person autorelease];//放入自动释放池
}

//构造方法自定义 不使用@synthesize 
-(People *)initWithName:(NSString*) name
                 andAge:(NSInteger) age
              andSchool:(NSString*) school
{
    if(self = [super init])
    {
        self.name = name;
        self.age = age;
        self.school = school;
    }
    
    return self;
}

+(People *)PeopleWithName:(NSString*) name
                   andAge:(NSInteger) age
                andSchool:(NSString*) school
{
    People * person = [[People alloc] initWithName:name andAge: age andSchool:school];
    return [person autorelease];//放入自动释放池
}

@end

//
//  main.m
//  Constructor
//  DRAGON
//  Created by 5016 on 13-12-2.
//  Copyright (c) 2013年 dradon. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "People.h"

int main(int argc, const char * argv[])
{

    //无参构造方法
    People* person1 = [People _People];
    person1.name = @"DRAGON";
    person1.age = 23;
    person1.school = @"GDOU";
    NSLog(@"我是%@,今年%ld岁,就读于%@.",person1.name,person1.age,person1.school);
    //带参构造方法
    People* person2 = [People PeopleWithName:@"XX" andAge:18 andSchool:@"SCNU"];
    NSLog(@"我是%@,今年%ld岁,就读于%@.",person2.name,person2.age,person2.school);

    return 0;
}

以上是笔者仿照别的高级语言里,使用一个(-)类方法,加上一个(+)静态方法,结合起来做成一个构造方法,这样看起来可读性就好多了.

其实原理是借助一个类方法初始化对象,然后使用静态方法返回.但是要注意的是,返回对象引用的同时需要把引用设置成autorelease

Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的Autorelease
pool中,当该pool被释放时,该pool中的所有Object会被调用Release。

在Iphone项目中,大家会看到一个默认的Autorelease pool,程序开始时创建,程序退出时销毁,

按照对Autorelease的理解,岂不是所有autorelease pool里的对象在程序退出时才release, 这样跟内存泄露

有什么区别?

答案:对于每一个Runloop, 系统会隐式创建一个Autorelease pool,这样所有的release pool会构成一个象

CallStack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的Autorelease pool会被销毁,这样这个

pool里的每个Object会被release。


抱歉!评论已关闭.