【黑马程序员】---Objective-C内存管理总结

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


Objective-C内存管理


基本数据类型存储在栈中,系统会自动释放存储空间,而OC对象存储在堆中,系统不会自动回收对象,故而引起内存管理。


1.引用计数器的基本操作

每一个对象都有一个引用计数器,它在内存中占用4个字节

(1)方法的基本使用
  1> retain :计数器+1,会返回对象本身
 2> release :计数器-1,没有返回值
 3> retainCount :获取当前的计数器
  4> dealloc
当一个对象要被回收的时候,就会调用
一定要调用[super dealloc],这句调用要放在最后面

(2).概念
 1> 僵尸对象 :所占用内存已经被回收的对象,僵尸对象不能再使用
 2> 野指针 :指向僵尸对象(不可用内存)的指针,给野指针发送消息会报错(EXC_BAD_ACCESS)
 3> 空指针 :没有指向任何东西的指针(存储的东西是nil、NULL、0),给空指针发送消息不会报错

Person p = [[Person alloc ] init];
[p retain];
[p release];
int size = [p retainCount];
[p release]

// 当一个Person对象被回收的时候,就会自动调用这个方法
- (void)dealloc
{
    NSLog(@"Person对象被回收");
    
    // super的dealloc一定要调用,而且放在最后面
    [super dealloc];
}

心得体会:

(1)当使用alloc、new或者copy创建一个新对象时,新对象的引用计数器默认就是1

(2)当一个对象的引用计数器值为0时,那么它将被销毁,其占用的内存被系统回收

(3)不要直接调用dealloc方法

(4)  一旦对象被回收了,它占用的内存就不再可用,坚持使用会导致程序崩溃(野指针错误)

(5)OC不存在空指针错误,给空指针发送消息,不报错


2.set方法的内存管理

 内存管理代码规范:
  1.只要调用了alloc,必须有release(autorelease)对象不是通过alloc产生的,就不需要release
 
 2.set方法的代码规范


 1> 基本数据类型:直接复制

 - (void)setAge:(int)age
 { 
    _age = age;
 }
2> OC对象类型

 - (void)setCar:(Car *)car
 {
    // 1.先判断是不是新传进来对象
    if ( car != _car )
    {
        // 2.对旧对象做一次release
        [_car release];
 
        // 3.对新对象做一次retain
        _car = [car retain];
    }
 }
  3.dealloc方法的代码规范
  1> 一定要[super dealloc],而且放到最后面
  2> 对self(当前)所拥有的其他对象做一次release

 - (void)dealloc
 {
    [_car release];
    [super dealloc];
 }
心得体会:

如果你有个OC对象类型的成员变量,就必须管理这个成员变量的内存


3.@property

 1.set方法内存管理相关的参数
retain : release旧值,retain新值(适用于OC对象类型)
assign : 直接赋值(默认,适用于非OC对象类型)
copy   : release旧值,copy新值
 
 2.是否要生成set方法
  readwrite : 同时生成setter和getter的声明、实现(默认)
readonly  : 只会生成getter的声明、实现
 
 3.多线程管理
  nonatomic : 性能高 (一般就用这个)
atomic    : 性能低(默认)
 
 4.setter和getter方法的名称
setter : 决定了set方法的名称,一定要有个冒号 :
getter : 决定了get方法的名称(一般用在BOOL类型)

@interface Person : NSObject

// 返回BOOL类型的方法名一般以is开头
@property (getter = isRich) BOOL rich;

@property (nonatomic, assign, readwrite) int weight;

@property (readwrite, assign) int height;

@property (nonatomic, assign) int age;

@property (retain) NSString *name;
@end
心得体会:

(1)不同类型的参数可以组合使用。

(2)一般都会添加nonatomic参数,提高性能。


4.循环引用

当一个类引用了另外一个类,另一个类又引用了这个类的时候,就叫做循环引用。

@class Person;

@interface Card : NSObject

@property (nonatomic, assign) Person *person;

@end

#import "Card.h"

@interface Person : NSObject

@property (nonatomic, retain) Card *card;

@end
心得体会:这种代码编译会报错。当使用@class在两个类相互声明,就不会出现编译报错


@class  

仅仅是告诉编译器,Card是一个类

@class和#include的区别:

(1)#import方式会包含被引用类的所有信息,包括被引用类的变量和方法;@class方式只是告诉编译器在A.h文件中 B *b 只是类的声明,具体这个类里有什么信息,这里不需要知道,等实现文件中真正要用到时,才会真正去查看B类中信息

(2)@class相比#include而言,能提高效率。当#include引入的文件更改时,所有引入的文件都要重新编译一遍

心得体会:

(1)在.m实现文件中,如果需要引用到被引用类的实体变量或者方法时,还需要使用#import方式引入被引用类

(2)两端循环引用的解决方案是,一端用retain一端用assign。


5.autorelease

(1) 给某个对象发送一条autorelease消息时,就会将这个对象加到一个自动释放池中

(2)当自动释放池销毁时,会给池子里面的所有对象发送一条release消息

(3)调用autorelease方法时并不会改变对象的计数器,并且会返回对象本身

 @autoreleasepool
 {
    // 1
    Person *p = [[[Person alloc] init] autorelease];
 
 }
1> alloc之后调用了autorelease,又调用release
 @autoreleasepool
 {
    // 1
    Person *p = [[[Person alloc] init] autorelease];
	// 0
	[p release];
 }
 
 // 2> 连续调用多次autorelease
 @autoreleasepool
 {
    Person *p = [[[[Person alloc] init] autorelease] autorelease];
 }
自动释放池

(1) 在iOS程序运行过程中,会创建无数个池子。这些池子都是以栈结构存在(先进后出

(2)当一个对象调用autorelease方法时,会将这个对象放到栈顶的释放池

// 自动释放池的创建方式
 // 1> iOS 5.0前
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
 [pool release]; // [pool drain];
 
 
 // 2> iOS 5.0 开始
 @autoreleasepool
 {
    
 }
心得体会:

(1)autorelease实际上只是把对release的调用延迟了,对于每一次autorelease,系统只是把该对象放入了当前的autorelease pool中,当该pool被释放时,该pool中的所有对象会被调用Release。


6.autorelease应用

(1)系统自带的方法里面没有包含alloc、new、copy,说明返回的对象都是autorelease的。

NSString *str2 = [NSString stringWithFormat:@"age is %d", 10];
(2)开发中经常会提供一些类方法,快速创建一个已经autorelease过的对象

 + (id)person
 {
    return [[[self alloc] init] autorelease];
 }
心得体会:

(1)创建对象时不要直接用类名,一般用self,这样于子类调用。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你以前使用过其他面向对象编程语言,那么学习Objective-C的基本语法会相对容易一些。Objective-C在许多传统的面向对象概念上有所体现,例如封装、继承和多态。然而,Objective-C也有一些重要的不同之处。如果你之前没有编写过任何编程语言的程序,那么在开始学习Objective-C之前,建议你先对相关概念进行一些基础的了解。了解对象的使用和对象的架构对于创建iPhone应用程序非常重要。Objective-C是C语言的超集,所以对C语言的了解也会对学习Objective-C有所帮助。希望这些信息对你有所帮助。如果你想进一步学习Objective-C的教程,可以参考Objective-C的@property详解、Objective-C入门教程03:属性(@property和@synthesize)、OC点语法和变量作用域、IOS SEL (@selector) 原理及使用总结、关于OC中的block自己的一些理解、Objective-C程序设计(电子书自行百度)等资料。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Objective-C 入门教程](https://blog.csdn.net/u010029439/article/details/106176034)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Objective-C 30分钟入门教程](https://blog.csdn.net/weixin_30488313/article/details/96036745)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值