为什么80%的码农都做不了架构师?>>>   

一 init的疑惑

init是OC的构造方法,也即是初始化方法。init常见于创建对象实例,假如现有Person这个类,新建一个Person对象实例时:

Person *person = [ [Person alloc] init];

以上代码执行的时候,实际实现了以下三个过程:

  • 向Person类发送了alloc消息,在堆内存中创建了该类的对象

  • 对象收到init消息后,进行对象的初始化

  • 返回对象中堆内存中的地址,赋值给person指针变量

1 未重写init方法

给对象分配内存空间后,需要初始化对象,才能使用该对象。但后来自己做了尝试,当给对象分配内存后,不初始化对象,还是可以操作对象中的实例变量和方法的:

// Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property NSString *name;
@property int age;
/** 测试方法*/
- (void)testMethod;
@end
// Person.m
#import "Person.h"
@implementation Person
- (void)testMethod {NSLog(@"This is test method.");
}
@end

然后在main.m中创建对象来进行测试:

// main.m
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {@autoreleasepool {   // 为Person对象申请内存空间,但未初始化 Person *person = [Person alloc];NSLog(@"\nperson: %@\nName: %@\nAge: %d",person, person.name, person.age);[person testMethod];}return 0;
}

输出结果:

2015-08-08 23:50:23.223 OC-类的练习01[484:9197]
person: <Person: 0x100206730>
Name: (null)
Age: 0
2015-08-08 23:50:23.224 OC-类的练习01[484:9197] This is test method.

2 重写init方法

在以上代码的基础上,重写Person类的init方法:

// Person.m
#import Person.h
@implementation Person
- (void)testMethod {NSLog(@"This is test method.");
}- (instancetype)init {if (self = [super init]) {_age = 1;_name = @"Test";}return self
}
@end

再在main.m中添加测试代码:

// main.m
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {@autoreleasepool {   // 为Person对象申请内存空间,但不初始化 Person *person = [Person alloc];NSLog(@"\nperson: %@\nName: %@\nAge: %d",person, person.name, person.age);[person testMethod];// 初始化对象person = [person init];NSLog(@"\nperson: %@\nName: %@\nAge: %d",person, person.name, person.age);}return 0;
}

输出结果:

2015-08-09 09:55:19.059 OC-类的练习01[458:9440]
person: <Person: 0x1001064f0>
Name: (null)
Age: 0
2015-08-09 09:55:19.060 OC-类的练习01[458:9440] This is test method.
2015-08-09 09:55:19.060 OC-类的练习01[458:9440]
person: <Person: 0x1001064f0>
Name: Test
Age: 1

个人理解是,在向Person类发送alloc消息创建了对象后,内存已经将实例变量设为了最原始的值,比如这里的Age默认0,Name默认null,并可以操作其对象方法。而在未重写init方法之前发送init消息时,Age和Name的值保持跟未初始化时一致。在重写了init方法之后,再发送init消息时,则按照重写方法来设置属性的初始值。

不过很迷惑,这跟书上的说法不一致。《ios编程》原话:任何一个对象都必须在创建并且初始化后才能使用(page31)。在网上未能找到更详尽的解释,后续如有新的进展再做跟进。

二 定制自己的初始化方法

默认的init方法不一定适用每个场景,有时需要定制自己的初始化方法。继续以Person类作扩展,在Person.h中声明initWithName:(NSString *)name Age:(int)age方法:

// Person.h
@interface Person : NSObject...
/** 定制自己的初始化方法*/
- (instancetype)initWithName:(NSString *)name Age:(int)age;
@end

并在Person.m中添加以下代码:

// Person.m
#import Person.h
@implementation Person...
- (instancetype)initWithName:(NSString *)name Age:(int)age {if (self = [super init]) {_name = name;_age = age;}return self;
}
@end

在main.m中删除之前的测试代码,直接采用自定义的初始化方法来创建对象:

// main.m
#import <Foundation/Foundation.h>
#import "Person.h"int main(int argc, const char * argv[]) {@autoreleasepool {// 采用自定义初始化方法创建对象 Person *person = [[Person alloc] initWithName:@"Tom Smith" Age:20];NSLog(@"\nName: %@\nAge: %d", person.name, person.age);    }return 0;
}

输出结果:

2015-08-09 10:20:50.780 OC-类的练习01[471:13356]
Name: Tom Smith
Age: 20

三 重写description方法

description方法,其实类似于java中的toString方法。如果以“NSLog(@"%@", person);”的形式打印时,只会输出person对象的内存地址,重写该方法可以输出我们需要的信息:

// Person.m
@implementation Person...
- (NSString *)description {return [[NSString alloc] initWithFormat:@"\nDescription\nName: %@\nAge: %d",_name, _age];
}
@end

然后在main.m中直接打印:

// main.m
#import <Foundation/Foundation.h>
#import "Person.h"int main(int argc, const char * argv[]) {@autoreleasepool {// 采用自定义初始化方法创建对象 Person *person = [[Person alloc] initWithName:@"Tom Smith" Age:20];NSLog(@"%@", person);    }return 0;
}

输出结果:

2015-08-09 10:41:50.242 OC-类的练习01[494:17251]
Description
Name: Tom Smith
Age: 20

转载于:https://my.oschina.net/ljunb/blog/489714

OC基础-关于构造方法相关推荐

  1. OC基础第四讲--字符串、数组、字典、集合的常用方法

    OC基础第四讲--字符串.数组.字典.集合的常用方法 字符串.数组.字典.集合有可变和不可变之分.以字符串为例,不可变字符串本身值不能改变,必须要用相应类型来接收返回值:而可变字符串调用相应地方法后, ...

  2. OC基础回想(十二)协议

    在OC基础(十一)中我们讨论了类别和非正式协议的奇异之处.在使用非正式协议时.能够仅仅实现你想要获得响应的方法.也不必在对象中声明不论什么内容来表示该对象可用作托付对象. 全部这些任务能够用最少的代码 ...

  3. OC基础 代理和协议

    OC基础 代理和协议 1.协议 (1)oc语言中得协议:一组方法列表,不需要我们自己实现,由遵守协议的类来实现协议所定制的方法. (2)协议的使用步骤:制定协议-->遵守协议-->实现协议 ...

  4. OC基础1:一些基本概念

    "OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 1.关于类方法和实例方法: (1).类方法 ...

  5. OC基础15:内存管理和自动引用计数

    "OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 1.什么是ARC? (1).ARC全名为A ...

  6. oc基础 不可变字符串的创建和使用

    oc基础  不可变字符串的创建和使用 简介:下面都是字符串基本用法. 1.字符串的创建 //创建oc常量字符串NSString *str=@"hello world!";NSLog ...

  7. iOS开发面试知识整理 – OC基础 (二)

    iOS | 面试知识整理 – OC基础 (二) 1.C和 OC 如何混编 xcode可以识别一下几种扩展名文件: .m文件,可以编写 OC语言 和 C 语言代码 .cpp: 只能识别C++ 或者C语言 ...

  8. OC基础学习 调用方式

    OC基础学习 调用方式 调用方法: C++里,送一个消息给对象(或者说调用一个方法)的语法如下: obj.method(argument); Objective-C则写成: [obj method: ...

  9. iOS战记 ----OC基础语法之战(一)

    iOS战记  ----OC基础语法之战(一) 一个机械设计者的转行之战. 火车一个年轻的程序员和一个项目经理登上了一列在山里行驶的火车,他们发现列车上几乎都坐满了,只有两个在一起的空位,这个空位的对面 ...

  10. ios开发之OC基础-类和对象

    ios开发之OC基础-类和对象 本系列的文章主要来自于个人在学习前锋教育-欧阳坚老师的iOS开发教程之OC语言教学视频所做的笔记,边看视频,边记录课程知识点.建议大家先过一遍视频,在看视频的过程中记录 ...

最新文章

  1. java 观察者模式示例_Java中的观察者设计模式-示例教程
  2. 按钮旁边加一个提示_地铁站的那些“红色按钮”,你知道是干啥用的吗?乱按可能被拘留...
  3. leetcode83,删除有序链表中的重复元素
  4. js json制表符报错_llhttp是如何使Node.js性能翻倍的?
  5. Python3 高级编程技巧(部分)
  6. [BZOJ1877][SDOI2009]SuperGCD
  7. 八、Android性能优化之电量优化(二)
  8. 程序员的思维修炼7——积累经验
  9. 在PHP网页中显示MySQL数据库内容
  10. 南阳师范计算机与信息技术学院,刘军(计算机与信息技术学院)老师 - 南阳师范学院 - 院校大全...
  11. MySQL安装步骤【亲测可用】
  12. 【设计开发命名必备】英语单词缩写规则
  13. Machine Learning 简介与学习路线
  14. TS中ts和.d.ts文件的区别
  15. linux段错误core dumped,Linux下Segmentation fault(core dumped)简单调试方法
  16. 电脑上打开chm文件时系统提示:不能打开文件:mk:@MSITStore:(文件路径)
  17. 雷军内部信:米家有品拆分 做独立电商
  18. linux进不去root,进不了root
  19. Oracle递归查询的原理
  20. IoT开源平台Thingsboard二次开发研究

热门文章

  1. 字节跳动一面:i++ 是线程安全的吗?
  2. 15000 字的 SQL 语句大全
  3. 程序是一座城,八年来我深陷其中
  4. NLP模型BERT和经典数据集!
  5. SVM算法在项目实践中的应用!
  6. 一文详尽系列之K-means算法
  7. GitHub 2021年度报告发布:中国755万开发者排名全球第二!
  8. 哈哈哈哈哈哈!当前的人工智能有多智障?
  9. Hinton再挖新坑:改进胶囊网络,融合Transformer神经场等研究
  10. 《最受欢迎的女友职业排行榜 Top10》