#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的更多相关文章

  1. OC基础-day02

    #pragma mark - Day02_01_对象的创建与使用 1)如何通过类创建一个对象 1. 类是抽象的,无法直接使用 2. 对象是类的一个具体实现,可以直接使用 3. 语法 类名 *对象名 = ...

  2. iOS代码规范(OC和Swift)

    下面说下iOS的代码规范问题,如果大家觉得还不错,可以直接用到项目中,有不同意见 可以在下面讨论下. 相信很多人工作中最烦的就是代码不规范,命名不规范,曾经见过一个VC里有3个按钮被命名为button ...

  3. 用C语言封装OC对象(耐心阅读,非常重要)

    用C语言封装OC对象(耐心阅读,非常重要) 本文的主要内容来自这里 前言 做iOS开发的朋友,对OC肯定非常了解,那么大家有没有想过OC中NSInteger,NSObject,NSString这些对象 ...

  4. 嵌入式&iOS:回调函数(C)与block(OC)传 参/函数 对比

    C的回调函数: callBack.h 1).声明一个doSomeThingCount函数,参数为一个(无返回值,1个int参数的)函数. void DSTCount(void(*CallBack)(i ...

  5. 嵌入式&iOS:回调函数(C)与block(OC)回调对比

    学了OC的block,再写C的回调函数有点别扭,对比下区别,回忆记录下. C的回调函数: callBack.h 1).定义一个回调函数的参数数量.类型. typedef void (*CallBack ...

  6. WebViewJavascriptBridge源码探究--看OC和JS交互过程

    今天把实现OC代码和JS代码交互的第三方库WebViewJavascriptBridge源码看了下,oc调用js方法我们是知道的,系统提供了stringByEvaluatingJavaScriptFr ...

  7. OC泛型

    OC泛型 泛型是程序设计语言的一种特性,他主要是为了限制类型的,比如OC中的数组,你可以限制他里面装的是NSString类型,泛型的话JAVA和C++都有的,大家要是对泛型不了解的话可以去百度一下. ...

  8. iOS学习15之OC集合

    1.数组类 1> 回顾C语言数组 数组是一个有序的集合, 来存储相同数据类型的元素. 通过下标访问数组中的元素,下标从 0 开始. 2> 数组 数组是一个有序的集合,OC中的数组只能存储对 ...

  9. JS 与OC 交互篇

    完美记录交互 CSDN博客: (OC调用JS) http://blog.csdn.net/lwjok2007/article/details/47058101 (JS调用OC) http://blog ...

随机推荐

  1. Remarks on a preprint

    Page 2 Line 1, "reads" should be "read". Page 2 Line 5, "are initial veloci ...

  2. linux命令 cp 递归复制 带权限复制

    cp -r 递归复制源目录下所有文件及子目录 到 目标目录或文件 cp -p 把源文件或目录下的所具有的权限一同复制 到 目标目录或文件

  3. SQLServer使用规范(转载)

    SQLServer使用规范 常见的字段类型选择 1.字符类型建议采用varchar/nvarchar数据类型 2.金额货币建议采用money数据类型 3.科学计数建议采用numeric数据类型 4.自 ...

  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 ...

  5. Response.Write,Page.RegisterClientScriptBlock和Page.RegisterStartupScript的区别

    Response.Write("<script>");输出在文件头部,一打开就执行. RegisterClientScriptBlock一般返回的是客户端函数的包装, ...

  6. arm汇编--ubuntu12.04 安装arm-linux交叉编译环境

    1. 安装标准的C开发环境,由于Ubuntu安装默认是不安装的,所以需要先安装一下:sudo apt-get install gcc g++ libgcc1 libg++ make gdb 2.从ft ...

  7. Result

    1.常用四种类型: a)          dispatcher(默认) 服务器跳转(普通转发),就是forward到一个JSP或者HTML或者其他结果页面,不能是Action 视图请求地址是     ...

  8. [置顶] 分析Java死锁:分析jstack日志

    本文中我将展示一段垃圾代码,这段代码会产生死锁,这样围绕这段代码重点展示三种不同的方法来分析线程日志,从而得知什么地方有问题. 下面的讨论将用到两个类 Account 和 DeadlockDemo c ...

  9. MySQL自定义查询字段排序

    同事在做抽奖排名的时候有个问题 需要按照 一等奖 二等奖 三等奖 未中奖 的形式输出数据 问到我如何排序. 数据库设计如下 用一个prize_code字段标示了是否中奖 1是一等奖 2是二等奖 3是三 ...

  10. spring boot 实践

    二.实践 一些说明: 项目IDE采用Intellij(主要原因在于Intellij颜值完爆Eclipse,谁叫这是一个看脸的时代) 工程依赖管理采用个人比较熟悉的Maven(事实上SpringBoot ...