OC加强-day02

 

 

#program mark - 01 @class关键字 [掌握]

1.当两个头文件互相引用的时候,如果双方都是用#import来引入对方的头文件,就会造成死循环,编译不通过

 

解决方案:其中一边不要使用#import去引用对方的头文件,而是用@calss关键字,class作用仅仅是来标识一下这个类

2.当类A使用@class去引用类B的时候,如果类A的内部需要访问类A的属性或方法,则在类A.m#importB.h

 

3.对比#import@class

1).#import是一个预处理命令,将文件的内容拷贝到写指令的地方

2).@class不是一个预处理命令,不会将文件的内容拷贝出来,只是告诉编译器有这么一个类

 

 

 

"强调

1.两个类AB,如果头文件互相#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.当自动释放池结束的时候,仅仅是对存储在自动释放池中的对象放松1release消息,而不是销毁对象

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 175634的时候, 注册了一个账号(名称:itcast 密码:123456

* 张三的生日是1998-7-4 184624

* 张三在2010-8-8 92344的时候, 发布一条微博

* 文字内容  @“今天心情不错

* 图片 @“goodDay.png”

* 发表时间

* 作者

* 转发的微博

* 评论数 100

* 转发数 290

* 点赞数 2000

 

* 李四在2006-9-8 192654的时候, 注册了一个账号(名称:lisiitcast 密码:654321

* 李四的生日是1999-9-6 141628

* 李四在2011-8-8 204709的时候, 转发了张三之前发布的微博 ,并且还附带了一句话:@“今天心情确实不错

* 评论数 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对象统一用strongOC对象统一使用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:ARCMRC,当徐行的类型是非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 MRCARC的兼容

 

 

 

#program mark - 15 MRC程序转换为ARC程序 [听懂]

转换非常粗暴,极可能会出现问题,不要轻易去转

 

 

#program mark - 16 分类的简单使用 [掌握]

 

 

"强调

1.分类是干什么的?

当一个类包含了非常多属于不同范畴的方法的时候,此时我们通常将这个类用多个文件来实现.有一个类叫本类,剩余的叫做分类

 

2.练习:创建一个网络工具本类,YYNetworkTools,给这个类添加分类Download,负责下载.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/MKxiaoyue/p/5707937.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值