OC加强-day02
#program mark - 01 @class关键字 [掌握]
1.当两个头文件互相引用的时候,如果双方都是用#import来引入对方的头文件,就会造成死循环,编译不通过
解决方案:其中一边不要使用#import去引用对方的头文件,而是用@calss关键字,class作用仅仅是来标识一下这个类
2.当类A使用@class去引用类B的时候,如果类A的内部需要访问类A的属性或方法,则在类A的.m内#import类B的.h
3.对比#import和@class
1).#import是一个预处理命令,将文件的内容拷贝到写指令的地方
2).@class不是一个预处理命令,不会将文件的内容拷贝出来,只是告诉编译器有这么一个类
"强调
1.两个类A和B,如果头文件互相#import,编译和运行没有问题.
2.一旦A中有B这个属性或者B中有A这个属性,直接就报错了.
3.怎么解决,一端用#import引入,另一端用@class
//需求
书提供一个方法给外界,所有者把名子签上去
由于没有真正的导入头文件,所以在Book的.m中无法访问owner对象属性的内容,此时就需要在Book.m中导入MKStudent.h
"重要
#import和@class区别
#import是预处理指令,是防止了重复包含文件的#include,
@class 不是是预处理指令,只是告诉编译器有这么个类,并且不会引入文件
#program mark - 02 循环retain [掌握]
1.对象的销毁不是因为调用了dealloc方法,
2.对象的retainCount-->0--->销毁--->dealloc
3.什么是循环retain
在MRC下,两个对象互相拥有对方做属性,如果都给对方赋值了,就会导致两个对象都无法释放
4.怎么解决循环retain
一端用retain一端用assgin,可以实现其中一个对象调用dealloc方法释放另外一方,最终都能释放
#program mark - 03 自动释放池的使用 [掌握]
1什么是自动释放池
自动释放池就是一对大括号包裹着的作用域,只不过前半部分多了一个@autoreleasepool来修饰
@autoreleasepool{
int num = 10;
}
2.和普通的作用域区别?
自动释放池可以在自动释放池结束的时候,对调用了autorelease的方法的对象,进行一次release
@autoreleasepool{
MKPerson *xiaoyue = [[MKPerson new] autorelease];
}
3.有什么用?
防止对于alloc/new出来的对象忘记手动调用release
#program mark - 04 使用自动释放出的七大注意 [掌握]
1.只有在自动释放池中调用了对象的autorelease方法,这个对象才会被存储到这个自动释放池中,如果只是将对象的创建代码写在自动释放池中,而没有调用这个对象的autorelease方法,是不会将这个对象存储到这个自动释放池中的
2.对象的创建可以在在动释放池的外面,在自动释放池之中,调用对象的autorelease方法,就可以将这个对象存储到这个自动释放池中,将一个对象存储到自动释放池中最重要的步骤是调用这个对象的autorelease方法,这句代码一定要放在自动释放池中
3.当自动释放池结束的时候,仅仅是对存储在自动释放池中的对象放松1条release消息,而不是销毁对象
4.如果在自动释放池中,调用同一个对象的autorelease方法多次,就会将对象储存多次到自动释放池中,在自动释放池结束的时候,会为对象发送多条release消息,这样就会出现僵尸对象错误,所有一个自动释放池中,只autorelease 一次,只将这个对象释放一次,否则就会出现野指针错误
5.如果在自动释放池中,调用了存储到自动释放池的对象的release方法,在自动释放池结束的时候,还会再调用对象的release方法,就会造成野指针操作
6.将对象存储到自动释放池,并不会是对象的引用计数器+1.
所以他的好处是:创建对象将对象存储在自动释放池,就不需要写release了
7.自动释放池可以嵌套
调用对象的autorelease方法会将对象加入到当前的自动释放池中,只有在当前自动释放池结束的时候才会像对象发送release消息
"强调"
1.需要自动释放池帮助完成release操作的对象,不一定是在自动释放池中创建的,只要这个对象在自动释放池中调用autorelease即可
"随堂代码/04 使用自动释放出的七大注意/1_需要协助release的对象不一定在自动释放池中创建
int main(int argc, const char * argv[]) {
MKPerson *xiaoyue = [MKPerson new];
@autoreleasepool {
[xiaoyue autorelease];
NSLog(@"---------------");
}
return 0;
}
2.自动释放池可以嵌套
对象在哪个自动释放池结束的时候release,就看对象在哪个autoreleasepool中调用了autorelease方法
"核心代码
int main(int argc, const char * argv[]) {
MKPerson *xiaoyue1 = [[MKPerson alloc] initWithName:@"A"] ;
@autoreleasepool
{
MKPerson *xiaoyue2 = [[MKPerson alloc] initWithName:@"B"];
[xiaoyue2 autorelease];
@autoreleasepool
{
MKPerson *xiaoyue3 = [[MKPerson alloc] initWithName:@"C"] ;
@autoreleasepool
{
MKPerson *xiaoyue4 = [[MKPerson alloc] initWithName:@"D"];
[xiaoyue4 autorelease];
[xiaoyue1 autorelease];
[xiaoyue3 autorelease];
}
}
}
return 0;
}
#program mark - 05 自动释放池的规范 [掌握]
"强调
1.定义一个类,一般还要定义一个以类名开头的类方法,用来返回一个实例化对象,这是规范.苹果公司自己就是这么干的.
#program mark - 07 微博练习 [掌握]
设计一个微博app的部分类:
一、微博类 (Microblog)
属性:
* 文字内容
* 图片
* 发表时间 (可以用字符串表示NSString)
* 作者
* 被转发的微博
* 评论数
* 转发数
* 点赞数
二、作者类 (User)
* 名称
* 生日
* 账号
三、账号类 (Account)
* 账号名称
* 账号密码
* 账号注册时间 (使用结构体)
//分析
1.发一条微博-->内容--->作者(直到世界尽头)--->账号(157XXX 12XXX)
//微博类中有个作者属性
//作者类拥有账号属性
结论:定义类的顺序
1.账号类Account
1>@property 属性
* 账号名称 NSString
* 账号密码 int
* 账号注册时间 (使用结构体) struct
2>构造方法
3>dealloc
2.作者类User
1>@property 属性
* 名称 昵称 nickName
* 生日 struct
* 账号 Account
2>构造方法
3>dealloc
3.微博类Microblog
1>@property 属性
* 文字内容 NSString
* 图片 NSString url
* 发表时间 (可以用字符串表示NSString) struct
* 作者 User
* 转发的微博 Microblog
* 评论数 int
* 转发数 int
* 点赞数 int
2>构造方法
3>dealloc
模拟场景:
* 张三在2007-9-8 17:56:34的时候, 注册了一个账号(名称:itcast, 密码:123456)
* 张三的生日是1998-7-4 18:46:24
* 张三在2010-8-8 9:23:44的时候, 发布一条微博
* 文字内容 @“今天心情不错”
* 图片 @“goodDay.png”
* 发表时间
* 作者
* 转发的微博
* 评论数 100
* 转发数 290
* 点赞数 2000
* 李四在2006-9-8 19:26:54的时候, 注册了一个账号(名称:lisiitcast, 密码:654321)
* 李四的生日是1999-9-6 14:16:28
* 李四在2011-8-8 20:47:09的时候, 转发了张三之前发布的微博 ,并且还附带了一句话:@“今天心情确实不错”
* 评论数 10
* 转发数 20
* 点赞数 200
快捷代码块路径
/Users/你的小房子名字/Library/Developer/Xcode/UserData/CodeSnippets
//思路
//一条微博:内容,作者,作者有一个账号
//微博类中有作者属性,作者属性中有账号属性
//1.账号类 Account
* 账号名称 NSString
* 账号密码 int
* 账号注册时间 (使用结构体) struct
//2.作者类 User
* 名称 NSString 昵称
* 生日 struct
* 账号 Account
//3.微博类 Microblog
* 文字内容 NSString
* 图片 NSString URL
* 发表时间 (可以用字符串表示NSString) NSString
* 作者 User
* 转发的微博 Microblog
* 评论数 int
* 转发数 int
* 点赞数 int
"强调
1.类方法返回对象注意添加autorelease
2.自定义构造方法注意对OC对象调用set方法
#program mark - 08 ARC机制的概述 [掌握]
1.指针是什么?
无论指针变量还是指针常量都是表示地址.
2.什么是强指针
ARC环境下,OC对象
用__strong修饰的指针叫做强指针 (默认指针变量前面什么都不加 就是强指针)
3.什么是弱指针
ARC环境下,OC对象
用__weak修饰的指针叫做弱指针
4.ARC机制核心
1>对象内存管理代码不需要程序员写,由编译器实现
2>对象是否释放就看有没有强指针指向自己,如果有就不释放,如果没有立即释放.
"随堂代码/08 ARC机制的概述/1_强指针和弱指针
1.分析
int main(int argc, const char * argv[])
{
// {
MKPerson *per = [[MKPerson alloc] initWithName:@"无色"];
// }
NSLog(@"\n---------------");
return 0;
}
2.
int main(int argc, const char * argv[]) {
{
__weak MKPerson *xiaoyue2 = nil;
{
MKPerson *xiaoyue = [[MKPerson alloc] initWithName:@"xiaoyue"];
xiaoyue2 = xiaoyue;
}
NSLog(@"---------------");
}
return 0;
}
3.
int main()
{
__weak MKPerson *xiaoyue = [[MKPerson alloc] initWithName:@"xiaoyue"];
NSLog(@"---------------");
return 0;
}
#program mark - 09 第一个ARC程序 [掌握]
"强调
在ARC下给类添加@property属性,OC对象统一用strong非OC对象统一使用assgin
@property(nonatomic,strong) 类型 * 属性名
#program mark - 11 ARC机制下的循环引用 [掌握]
1.是什么?
当对象A中有一个对象B属性,对象B中又有一个对象A属性的时候,如果两边都使用strong来互相修饰,并实现双方的赋值,会导致对象A和对象B都无法释放.
"随堂代码/11 ARC机制下的循环引用/1_ARC循环引用
2.例子--ARC
1>需求
人类 Person
{
电脑属性
}
电脑类 Computer
{
人属性(所有者)
}
1)只是新建对象都能释放
2)只是有一边赋值了都能释放
3)两边都赋值了都不能释放
4)解决,一端用strong修饰,一边用weak修饰
3.解决:一端用weak,一端用strong
#program mark - 12 @property参数总结 [掌握]
1.与多线程相关的参数
atomic:
nonatomic:
这两个参数,无论在MRC还是ARC下都可以使用,基本上使用nonatomic
2.retain:只能在MRC模式下,当属性的类型是OC对象是,绝大多数场景下使用retain
assign:在ARC和MRC下,当徐行的类型是非OC对象的时候,一律用assign
在MRC模式下,出现循环引用的时候,1边使用assign一边使用retain
#program mark - 13 弱指针在对象被回收以后自动设置为nil [掌握]
1.什么弱指针
在ARC下用__weak修饰的指针叫做弱指针
"随堂代码/13 弱指针在对象被回收以后自动设置为nil/1_弱指针自动变为nil
2. 弱指针在它指向的对象被回收以后自动设置为nil
int main(int argc, const char * argv[]) {
__weak MKPerson * xiaoyueRou = nil;
NSLog(@"xiaoyueRou=%p",xiaoyueRou);
{
MKPerson *xiaoyue = [[MKPerson alloc] init];
NSLog(@"xiaoyue=%p",xiaoyue);
xiaoyueRou = xiaoyue;
NSLog(@"xiaoyueRou=%p",xiaoyueRou);
}
NSLog(@"xiaoyueRou=%p",xiaoyueRou);
[xiaoyueRou test];//给空指针发送任何消息都是没有效果
return 0;
}
//运行结果
2016-04-15 11:01:04.090 1_弱指针自动变为nil[1072:494299] xiaoyueRou=0x0
2016-04-15 11:01:04.091 1_弱指针自动变为nil[1072:494299] xiaoyue=0x100111490
2016-04-15 11:01:04.092 1_弱指针自动变为nil[1072:494299] xiaoyueRou=0x100111490
2016-04-15 11:01:04.092 1_弱指针自动变为nil[1072:494299] 人对象被释放了!
2016-04-15 11:01:04.092 1_弱指针自动变为nil[1072:494299] xiaoyueRou=0x0
3.补充 ARC下@autoreleasepool用法
1>你就当做一堆花括号用就可以了,内部所有内存管理代码,由编译器帮助实现,包括autorelease
//下面代码执行效果一模一样
int main(int argc, const char * argv[]) {
@autoreleasepool
{
MKPerson *xiaoyue = [[MKPerson alloc] init];
}
{
MKPerson *xiaoyue2 = [[MKPerson alloc] init];
}
return 0;
}
2016-04-15 11:09:23.198 1_弱指针自动变为nil[1132:533415] 人对象被释放了!
2016-04-15 11:09:23.199 1_弱指针自动变为nil[1132:533415] 人对象被释放了!
2.在ARC下创建一个类,类方法生成对象,不需要再添加autorelease.
"随堂代码/13 弱指针在对象被回收以后自动设置为nil/2_ARC@autoreleasepool
//下面代码会报错
+(instancetype)person
{
return [[[self alloc] init] autorelease];
}
#program mark - 14 MRC和ARC的兼容
#program mark - 15 MRC程序转换为ARC程序 [听懂]
转换非常粗暴,极可能会出现问题,不要轻易去转
#program mark - 16 分类的简单使用 [掌握]
"强调
1.分类是干什么的?
当一个类包含了非常多属于不同范畴的方法的时候,此时我们通常将这个类用多个文件来实现.有一个类叫本类,剩余的叫做分类
2.练习:创建一个网络工具本类,YYNetworkTools,给这个类添加分类Download,负责下载.
OC加强-day02的更多相关文章
- OC基础-day02
#pragma mark - Day02_01_对象的创建与使用 1)如何通过类创建一个对象 1. 类是抽象的,无法直接使用 2. 对象是类的一个具体实现,可以直接使用 3. 语法 类名 *对象名 = ...
- iOS代码规范(OC和Swift)
下面说下iOS的代码规范问题,如果大家觉得还不错,可以直接用到项目中,有不同意见 可以在下面讨论下. 相信很多人工作中最烦的就是代码不规范,命名不规范,曾经见过一个VC里有3个按钮被命名为button ...
- 用C语言封装OC对象(耐心阅读,非常重要)
用C语言封装OC对象(耐心阅读,非常重要) 本文的主要内容来自这里 前言 做iOS开发的朋友,对OC肯定非常了解,那么大家有没有想过OC中NSInteger,NSObject,NSString这些对象 ...
- 嵌入式&iOS:回调函数(C)与block(OC)传 参/函数 对比
C的回调函数: callBack.h 1).声明一个doSomeThingCount函数,参数为一个(无返回值,1个int参数的)函数. void DSTCount(void(*CallBack)(i ...
- 嵌入式&iOS:回调函数(C)与block(OC)回调对比
学了OC的block,再写C的回调函数有点别扭,对比下区别,回忆记录下. C的回调函数: callBack.h 1).定义一个回调函数的参数数量.类型. typedef void (*CallBack ...
- WebViewJavascriptBridge源码探究--看OC和JS交互过程
今天把实现OC代码和JS代码交互的第三方库WebViewJavascriptBridge源码看了下,oc调用js方法我们是知道的,系统提供了stringByEvaluatingJavaScriptFr ...
- OC泛型
OC泛型 泛型是程序设计语言的一种特性,他主要是为了限制类型的,比如OC中的数组,你可以限制他里面装的是NSString类型,泛型的话JAVA和C++都有的,大家要是对泛型不了解的话可以去百度一下. ...
- iOS学习15之OC集合
1.数组类 1> 回顾C语言数组 数组是一个有序的集合, 来存储相同数据类型的元素. 通过下标访问数组中的元素,下标从 0 开始. 2> 数组 数组是一个有序的集合,OC中的数组只能存储对 ...
- JS 与OC 交互篇
完美记录交互 CSDN博客: (OC调用JS) http://blog.csdn.net/lwjok2007/article/details/47058101 (JS调用OC) http://blog ...
随机推荐
- Remarks on a preprint
Page 2 Line 1, "reads" should be "read". Page 2 Line 5, "are initial veloci ...
- linux命令 cp 递归复制 带权限复制
cp -r 递归复制源目录下所有文件及子目录 到 目标目录或文件 cp -p 把源文件或目录下的所具有的权限一同复制 到 目标目录或文件
- SQLServer使用规范(转载)
SQLServer使用规范 常见的字段类型选择 1.字符类型建议采用varchar/nvarchar数据类型 2.金额货币建议采用money数据类型 3.科学计数建议采用numeric数据类型 4.自 ...
- HDOJ/HDU 1982 Kaitou Kid - The Phantom Thief (1)(字符串处理)
Problem Description Do you know Kaitou Kid? In the legend, Kaitou Kid is a master of disguise, and c ...
- Response.Write,Page.RegisterClientScriptBlock和Page.RegisterStartupScript的区别
Response.Write("<script>");输出在文件头部,一打开就执行. RegisterClientScriptBlock一般返回的是客户端函数的包装, ...
- arm汇编--ubuntu12.04 安装arm-linux交叉编译环境
1. 安装标准的C开发环境,由于Ubuntu安装默认是不安装的,所以需要先安装一下:sudo apt-get install gcc g++ libgcc1 libg++ make gdb 2.从ft ...
- Result
1.常用四种类型: a) dispatcher(默认) 服务器跳转(普通转发),就是forward到一个JSP或者HTML或者其他结果页面,不能是Action 视图请求地址是 ...
- [置顶] 分析Java死锁:分析jstack日志
本文中我将展示一段垃圾代码,这段代码会产生死锁,这样围绕这段代码重点展示三种不同的方法来分析线程日志,从而得知什么地方有问题. 下面的讨论将用到两个类 Account 和 DeadlockDemo c ...
- MySQL自定义查询字段排序
同事在做抽奖排名的时候有个问题 需要按照 一等奖 二等奖 三等奖 未中奖 的形式输出数据 问到我如何排序. 数据库设计如下 用一个prize_code字段标示了是否中奖 1是一等奖 2是二等奖 3是三 ...
- spring boot 实践
二.实践 一些说明: 项目IDE采用Intellij(主要原因在于Intellij颜值完爆Eclipse,谁叫这是一个看脸的时代) 工程依赖管理采用个人比较熟悉的Maven(事实上SpringBoot ...