说到构造方法,我很想吐槽,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。