黑马程序员-------Objective-C基础3

------ android培训、java培训、期待与您交流! ----------

1.OC内存管理

1)范围:管理任何继承NSObject的对象,对其他的基本数据类型无效(堆区),否则会造成内存泄露

2)原理:任何对象都可能有用一个或多个所有者,只要一个对象至少还拥有一个所有者,它就会继续存在

3)对象的引用计数器,retain(+1)、release(-1)、retainCount得到引用计数器的值

4)内存管理的分类:MRC(手动管理)、ARC(自动管理)、垃圾回收(不支持)

2.引用计数器的使用

dealloc:释放对象

先调用[super dealloc]

我们创建一个项目,默认是ARC模式,先修改

//
//  main.m
//  内存管理
//
//  Created by fanyafang on 15/11/6.
//  Copyright © 2015年 itcast. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Person.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {

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

        NSUInteger count=[p retainCount];

        NSLog(@"%lu",count);

        //Person *p2=p;//不变
        //Person *p2=[p retain];//加1
        [p retain];//加1

        [p release];//减一
        [p release];//减一自动调用dealloc方法
        //证明p的空间被释放,可以在Person类中重写dealloc方法
    }
    return 0;
}

3.内存管理的原则

1)只要有人使用这个对象,这个对象就不会被回收

2)只要你想使用这个对象,那么就应该让这个对象的引用计数器加1

3)当你不想使用这个对象时,应该让对象的引用计数器减1

4)谁创建(new、malloc、copy)谁release

5)谁retain谁release

4.如果一个对象已经被释放了,这个对象就成为僵尸对象,再去使用这个对象就没有意义,默认不报错,需要开启僵尸对象检测

不能使用retain让僵尸对象起死回生

5.对象nil 类Nil NULL NSNull是一个对象

避免使用僵尸对象的方法是,对象释放以后,给对象赋值为nil

6.多个对象的内存管理

在set函数中先release实例对象,再retain传入的对象

//如果是同一个对象的话就不需要release和retain

if(_car!=car){

  [_car release];

  _car=[car retain];

}

在dealloc中,release实例对象

[_car release];

[email protected]参数

1.原子性atomic  nonatomic

2.读写readwrite readonly

3.内存管理assign retain copy

替换get方法名称setter=isVip,get方法名称getter=isVip

[email protected]的使用

使用import引入头文件时,如果头文件的内容发生了变化,此时所有引用这个头文件的类都需要重新编译

使用@class 类名;代替import

告诉编译器xxx是一个类,不需要重新编译

但是使用时会有提示错误,解决办法,在.m文件中再import一次

@class的可以解决循环引入问题,A类和B类互相import,使用class不会报错

9.循环retain会导致两个对象都会内存泄露

防止方法:1)让某个对象多释放一次(注意顺序)

2)推荐方法:一端使用assign,另一端使用retain

10.NSString对象

[email protected]

如果一个方法需要放回一个新建的对象,该对象何时释放?

方法内部不会释放,因为这样做会将对象立即释放而返回一个空对象,调用者也不会主动释放该对象

这个时候就发生了内存泄露

1)@autoreleasepool {}创建自动释放池

2)[对象 autorelease];//加入自动释放池,发送消息,释放池结束的时候调用对象的release

时间: 2024-12-21 13:18:07

黑马程序员-------Objective-C基础3的相关文章

黑马程序员—张老师基础加强7-动态代理

代理: 要为已经存在的多个具有相同接口的目标类的各个方法增加一些系统功能. 例如:异常处理,日志和计算方法的运行时间,事物管理等,怎么做 如 在运行前后增加计算时间的方法.show(){ sop(); } 编写一个与目标类具有相同接口的代理类,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码. 动态代理: 要为系统中的各种接口的类增加代理功能,那需要太多代理类. jvm可以在运行期间动态生成出类的字节码,这种动态生成的类往往被调用作代理类, 即动态代理类. jvm生成动态类

黑马程序员-c语言基础:各种数据类型的输出占位符

c语言中的输出操作相对java来说是比较麻烦的,每种数据类型的输出都有各自的占位符: 下面是各种数据类型的输出占位符: short/int : %d int a = 1; printf("这个整数是:%d", a); long: %ld; (long 是int得修饰,不能算是一种单独的数据类型,只是比int多了四个字节的存储空间) long long: %lld char : %c float/double : %f  float默认是6位小数输出:可以在%f中控制:例如:%.2f:输

黑马程序员-张老师基础5-泛型

泛型: 泛型只是提供给编译器.在编译完之后,生产字节码文件时就擦除类型信息,<>泛型就不在了 泛型的术语: 整个Arraylist<E>:称为泛型类型. Arraylist<E>中的E称为类型变量或类型参数 整个Arraylisst<Integer>称为:参数化的类型 Arraylist<Integer>中的Integer称为类型参数的实例. Arraylist<Integer>中的<>是typeof Arraylist称

黑马程序员——Java集合基础知识之Map

Map概念 要同时存储两个元素Key和Value,他们之间有映射关系,每个键不能重复,每个键只能映射到一个值. 当数据之间存在映射关系的时候,考虑使用Map集合. Map常用方法 如果添加的键原来有值,后添加的值会覆盖前面的值,并返回之前的值.put会返回来先添加的值,后添加的值会覆盖原有的值. Map tm =new TreeMap(); tm.put (key, value);//MAP没有add tm.remove (key) ;//去除一个key和对应的value,若不存在key返回nu

黑马程序员——Java集合基础知识之Collection

集合基础知识--Collection Java中集合框架由常用的Collection接口和Map接口组成,而Collection接口又有两个子接口,是List接口和Set接口,常用的集合框架由这三个类组成. List接口的功能方法 List的使用最为简单,创建集合,通过add方法添加元素,get方法获取元素,通过迭代器获取元素.List接口存放的数据无序的,添加速度快,但是查询速度慢,因为查询的时候必须遍历,每次都重头开始,效率较低.常用实现类有ArrayList,LinkedList. Lis

黑马程序员-C语言基础:指针类型与指针和数组、字符串的关系

//指针变量就是用来存储地址的,只能存储地址 格式:  int  *p;  这个p为指针变量:指针变量占8个字节 类型是用来说明这个指针指向的类型: 比如上边的int代表这个指针变量会指向int类型的存储空间: int *p = &a;//这样一句可以写,此时的*只是一个标志,表示这个*只是表示p是个指针: *p = &a;//这样写就错了:此时*p表示取p指向的空间的值: 指针疑问:指针既然都占据8个字节,那么为什么要划分类型, 是因为当用*p指针取值或者赋值的时候,知道该取几个字节,比

黑马程序员-C语言基础:数组和字符串

数组:数组的定义注意点 数组初始化正确写法: int args[5] = {1,23,32,4,5}; int args[5] = {12,23}; int args[5] = {[3]=23, [4]=13};//这种写法也可以,直接给其中角标为3和4的赋值 int args[] = {12,23,32};//中括号中没写数组大小,在大括号中一定要写具体数值 int args['A'] = {2,34,5}; 错误写法: int args[];//这样编译器不知道给你开辟多大的内存空间 int

黑马程序员_01_Java语言基础部分(数据类型与表达式、流程控制语句、数组与方法)

------- android培训.java培训.期待与您交流! ---------- Java语言主要由5中符号组成 标识符:数字.字母.美元符.下划线(注意不能数字开头) 关键字:goto和const保留了它们,但是Java没有使用. 运算符:注意运算符优先级(左结合和右结合要注意) 分隔符:注意+号可以分割字符串. 注释:三种注释. 数据类型与变量 常量: 整型 浮点型 字符:注意后面跟三个八进制(\ddd)和 四位unicode码(\u8bf7) (不区分大小写) 字符串 布尔型 变量:

黑马程序员——java多线程基础知识1

多线程 进程是一个正在执行的程序. cpu在同时执行这些程序,其实是跳跃式的,做快速的切换,时间很短.一个进程可能存在多条路径.迅雷的多路径.每一个进行执行都有一个执行顺序,该顺序是一个执行路径,或这叫一个控制单元.每一个进程至少有一个线程,线程就是进程中的一个独立的控制单元,线程控制进程的执行.jvm启动的时候会有一个进程就叫做java,exe,该进程中至少有一个线程在控制Java程序的执行 ,而且该线程的执行代码在 主函数中.该线程称为主线程.虚拟机至少也有两个线程,一个主线程执行,另一个负

黑马程序员——Java多线程基础知识2

多线程协同 线程间的通讯:我们对资源的操作动作不同,比如说两个卡车一个拉煤一个装煤.但是他们共享了一个资源. 怎么样把这个资源拿出来?怎样把车装满?这个资源当然是一个类,他里面的组成元素就是对象!!现在我们就要有操作对象的思想了,我用对象把这车装满,现在一车装一个对象. 等待唤醒机制: 用的不是sleep是wait.flag标记,这是两人沟通的方式.其实每个标记就要做一次等待或者notify,判断wait,改值notify.线程池.notify唤醒里面的线程,按顺序唤醒.wait和notify必