【GeekBand】objective-c basic1

  • 类与对象
  • 数据成员
  • 函数成员

TODO:

  • 初始化器和析构器
  • 继承
  • 多态

类与对象

Objective-C(以下简称OC) 是一种面向对象语言,因此除了基本数据类型,它具有类类型。OC 中类的声明形式类似:

 @interface MyClass: NSObject
 {
  NSString* private;  //实例变量
  @public NSString* public; //实例变量
 }
 @property int num;  //属性
 
 -(void)ObjectMethod: (int)num; //对象方法,又叫实例方法
 +(void)ClassMethod; //类方法
 
 -(NSString*)private ;
 -(void)setPrivate: (NSString*)str;
 
 @end

OC 用 @interface 声明类,相当于C++语法中的class关键字。@end表示声明的结束。OC中的大部分中大部分类都会直接或者间接继承自NSObject,这是因为NSObject中定义了一些OC对象通用的方法,比如定义一个类时[[MyClass alloc] init],其中allocinit方法就是在NSObject中定义的,否则我们就要在类定义中自己实现这两个方法。

OC中类的声明放在.h文件,类是现实存在.m文件。上面声明的类其实现类似:

 @implement MyClass
 
 -(void)ObjectMethod: (int)num
 {
  self.num = num;
 }
 
 +(void)ClassMethod 
 {
  NSLog(@"This ClassMethod");
 }
 
 -(NSString*)private {
  return private;
 }
 
 -(void)setPrivate: (NSString*)str {
  private = str
 }

定义一个类对象的语法如下:

 MyClass* myClass = [[MyClass alloc] init]

大概是因为OC中的类对象都是分配在堆上的,所以,类对象都声明为指针的形式。

数据成员:属性和实例变量

上述类声明中的有一个数据成员,就是

@property in num;

属性的存取方式

myClass.num = 5;
int someNum = myClass.num;

对于任何属性,编译器都会自动生成一个与之关联的实例变量。比如与num关联的实例变量是_num。同时还生成一个getter访问器方法和一个setter访问器方法。

-(int)num {
 return _num;
}

-(void)setNum: (int)num {
 _num = num;
}

可以发现这里的_num和它的两个访问器和我们在MyClass实现中定义的NSString* private;形式是类似的。
privatepublic一样是实例变量,不同的是,一般的实例变量(如:private)只能在类的内部访问,都是私有的。为了能在类的外部访问(如myClass->public = @"hello";),需要在实例变量声明语句加上@public前缀(如:public)。
虽然private不能在外部通过->来访问,但因为我们为private编写了getter访问器和setter访问器,在OC中,我们就可以使用myClass.private = @"world"这样的语法来访问private,其实编译器会自动将该语句转化成[myClass setPrivate:@"world"],也就是实际是调用setter方法来访问private实例变量的。
可想而知,如果没有属性,那么对于每个我们希望通过myClass.XXX形式来访问的实例变量,我们都需要为其编写两个访问器方法,这实在是太过繁琐。有了属性这个语法糖,就可以让编译器自动为我们完成这些工作了。
同样,有了属性,我们也不需要再使用@public关键字,通过->指针访问符来访问实例变量了。

需要注意的时,对于在.h.m文件中分别编写类声明和类实现代码情况,即我们通常所遵循的方式。外部使用时通过#import "xxx.h"只能知道xxx.h文件中的定义,如果我们将某个实例变量定义在xxx.m的实现代码中,那么就是为该实例变量加上@public前缀,外部对象也不能访问该实例变量,因为它根本不知道该实例变量的存在。这点对于方法也是成立的,尽管方法都是public的,但如果方法只在.m文件中定义,没有在.h文件中声明,那么对于外部对象该方法就相当于是私有的。相当于私有并不等于私有,这点在编译器报错时可以体现。只定义在.m文件中情况,访问时编译器会提示没有定义该实例变量或者方法,而如果是声明在.h文件中非@public实例变量,访问时编译器会提示该实例变量是受保护的。

函数成员:方法

OC中的方法都是public的,没有 private 和 protected 方法。
OC中类的方法分为实例方法类方法,声明形式如下

-(void)ObjectMethod: (int)num; //对象方法,又叫实例方法
+(void)ClassMethod; //类方法

在语法层面,实例方法就是通过实例对象来调用的方法,如[myClass ObjectMethod:10],定义时在方法名前加-前缀;类方法就是通过类名来调用的方法,如[MyClass ClassMethod],定义时在方法名前加+前缀。
[[MyClass alloc] init],其中alloc就是类方法,init就是实例方法。

类方法中是不能访问本类的实例成员的。在逻辑上类方法可以在类对象不存在时调用,此时实例变量都还不存在,那么通过类方法访问实例成员必然出错。即使类对象存在,假设有多个类对象,那么类方法是访问那个类对象的实例成员也是无法确定。在实现上,编译器会为实例方法自动添加指向当前对象的self指针参数,通过self就能确定所访问的对象。而类方法是没有self参数的,所以类方法无法确定是哪个类对象。

OC中方法的外部参数名不同,就是不同的方法。因此可以写方法名相同,参数类型和数量相同,以及返回值相同的,只有外部参数名不同的多个方法。

-(void)sum: (int)arg1 arg2: (int)arg2;
-(void)sum:(int)arg1 secondArg: (int)arg2;

这样的两个方法是可以同时存在的。

初始化器和析构器

初始化器

    MyClass* myClass = [[MyClass alloc] init]

OC中创建一个对象需要配合使用allocinit两个方法。正如方法名的字面意思,alloc方法用于分配对象空间,init方法用于对对象的实例变量进行初始化操作。
alloc方法在NSObject中已经定义,这也是我们的类要继承于NSObject的原因之一。alloc方法会将分配的内存空间用0来填充,这样所有的实例变量的值就会是0或者nil。
init的方法中,会先调用父类的init方法,再初始化自己的实例变量。
init是对象初始化器,在调用init之前还会调用一个类初始化器initialize

@implementation MyClass 
...
-(id)init {
    self = [super init];
    NSLog(@"this init");
    return self;
}

+(void)initialize {
    if self == [MyClass class] {
        NSLog(@"this is initialize");
    }
}
...
@end

在类定义中实现这两个初始化器,然后调用MyClass* myClass = [[MyClass alloc] init]
会输出如下结果:

结果

类型初始化器initialize只能有一个,而对象初始化器init可以有多个。

- (id)init;
- (id)initWithName: (NSString*)name;
- (id)initWithLocation: (NSPoint*)location;

在初始化器中,要使用实例变量,不要使用属性。

析构器 dealloc

在析构器中,主要做三件事

  1. ARC对对象属性的引用计数器减1,这个造作是自动完成。
  2. 手动释放我们自己分配的动态内存
  3. 关闭非内存资源,比如文件句柄,socket连接等
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容