`

内存管理和特性

阅读更多

#import <Foundation/Foundation.h>
#import "RetainTracker.h"
/**
 不用使用任何刚释放的内存,否则我们将可能误用陈旧的数据,从而引起各种各样的错误,而如果该内存已经加载了其他数据,我们将破坏这些数据
 对象的生命周期包括诞生(通过alloc或new方法实现),生存(接受消息和执行操作),交友(借助方法的组合和参数)以及当它们的生命结束时最终死去(被释放)
 cocoa采用了一种成为引用计数的技术,有时也叫保留计数。每个对象有一个与之相关联的整数,称作它的引用计数器或者保留计数器。当某段代码需要访问一个对象时,该代码将该对象的保留计数器值加1,表示‘我要访问该对象’
 当这段代码结束对象访问时,将对象的保留计数器值减1,表示它不再访问该对象。
 
 当使用alloc,new方法或者copy消息创建一个对象时,对象的保留计数器值被设置为1,要增加对象的保留计数器值,可以给对象发送一条retain信息。要减少对象的保留计数器值,可以给对象发送一条release信息。
 当一个对象因其计数器归0而即将被销毁时,objective-c自动向对象发送一条dealloc消息,你可以在自己的对象中重写dealloc方法,可以通过这种方法释放已经分配的全部相关资源。一定不要直接调用dealloc方法。
 可以利用objective-c在需要销毁对象时调用deallocff。
 要获取对象的保留计数器的当前值,可以发送retainCount信息。
 -(id) retain;--retain方法返回一个id类型的值,通过这种方式,可以嵌套执行带有其他信息发送参数的保留调用,增加对象的保留计数器值并要求对象完成某种操作,例如:[[car retain] setTire:tire atIndex:2]]
 -(void) release;
 -(unsinged) retainCount;
 */
int main (int argc, const char * argv[]) {
	//cocoa中有一个自动释放池的概念,它是一个存放实体的池,这些实体可能是对象,能够被自动释放
	/*
	 NSObject 提供了一个autorelease方法
	 -(id) autorelease; 该方法预先设定了一个着将来某个时间发送的release信息,其返回值是接收消息的对象。
	 retain消息采用了相同的机制,使嵌套调用更加容易。当给一个对象发送autorelease信息时,实际上上将该对象添加到NSAutoreleasePool中。当自动释放池被销毁时,会向该池中的所有对象方法release消息。
	 **/
	
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	//对象初始化
	/*
	 *创建对象到两种方法:1:[类名 new] 2:[[类名 alloc] init] 着两种方法是等价到,不过一般习惯用第二种方法
	 *
	 */
	RetainTracker  *track=[RetainTracker new];
	/*
	 alloc 分配对象 从操作系统中获得一块内存并将其指定为存放对象到实例变量到位置
	 init 初始化对象 从操作系统中取得一块内存,准备用于存储对象。init方法几乎总是返回它们正在初始化到对象。
	 **/
	//RetainTracker *t=[[RetainTracker alloc] init];
	
	NSLog(@"1==%d",[track retainCount] );
	[track retain];
	NSLog(@"2===%d",[track retainCount]);
	[track release];
	NSLog(@"3==%d",[track retainCount]);
	
	//drain方法只是清空自动释放池,而不销毁它,只适用于高版本
	//[pool releas];
     [pool drain];
    return 0;
}
/**
 当我们说某个实体“拥有一个对象”时就意味着该实体负责确保对其拥有的对象进行清理。
 如果一个对象具有指向其他对象的实例变量,则称该对象拥有这些对象
 
 访问方法里的保留和释放-------先保留新对象,然后再释放旧对象,
 
 -(void) setTire:(Engine *) newEngine{
 [newEngine retain];
 [engine release];
 engine=newEngine;
 }
 */

/**
 cocoa的内存管理规则
 1:当使用new,alloc,或者copy方法创建一个对象时,该对象的保留计数器值为1.当不再使用该对象时,你要负责向该对象发送一条release或autorelease消息。
 2:当通过任何其他方法获得一个对象时,则假设该对象的保留计数器值为1,且已经被设置为自动释放,你不需要执行任何操作来确保对象被清楚。如果你打算在一段时间内拥有该对象,则需要保留它并确保在操作完成时释放它
 3:如果你保留了某个对象,你需要最终释放或自动释放该对象,必须保持retain方法和release方法的使用次数相等。
 
 */
/**
 自动释放池被清楚的时间是完全确定的,要么是在你自己的代码中显示地销毁,要么是在事件循环结束时使用appkit销毁。你不必关系守护程序任何随机地销毁自动释放池。因为在调用函数到过程中自动释放池不会被销毁,所以你
 也不必保留使用到每一个对象
 **/
 //
//  RetainTrackr.h
//  MemoryManager
//
//  Created by 110 on 10-1-24.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import <Cocoa/Cocoa.h>


@interface RetainTracker : NSObject {
	float rain;
	float snow;
}
//特性
// @property 预编译指令的作用所自动声明属性的setter和getter方法。实际上属性的名称不必和实例变量的名称相同,但大多数情况下它们是一样的
@property float rain;
@property float snow;
//特性的扩展
/**
 retain:保留
 readonly:只读,只生成getter方法
 copy:复制
 nonatomic:不生成多线程代码
 readwrite:默认属性,可读写的
 */
//@property (retain,readonly,copy,) float rain;

@end

 //

//  RetainTrackr.m
//  MemoryManager
//
//  Created by 110 on 10-1-24.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "RetainTracker.h"


@implementation RetainTracker

//特性
//@synthesize 也是一种新的编译器功能,表示“创建该属性的访问器”
@synthesize rain;
@synthesize snow;



//init方法遵循标准的cocoa对象初始化方式
/*
 init方法应该完成那些工作???
	在该方法中,你要执行全新到初始化工作,给实例变量赋值并创建你到对象完成任务所需要到其他对象。
 ***/
 - (id) init
{
	//[super inti]----使超类完成它们自己到初始化工作
	/**
	 实例变量所在到内存位置到隐藏到self参数之间到距离使固定到。如果从init方法返回一个新对象,则需要更新self,以便其后到任何实例变量到引用可以被映射到正确到内存位置。这也是我们需要使用self=[super init]形式进行赋值到原因。
	 这个赋值操作只影响init方法中self到值,而不影响该方法范围以外到任何内存
	 */
	self = [super init];
	//如果在初始化一个对象时出现问题,则init方法可能返回nil
	if (self != nil) {
		
		NSLog(@"init : retain count of %d",[self retainCount]);
		
	}
	
	//init方法返回已经被初始化到对象
	return self;
}


/**
 指定初始化函数:
	类中到某个初始化方法被指派为指定初始化函数,该类的所有初始化方法使用指定初始化函数执行初始化操作。子类使用其超类的指定初始化函数实现超类的初始化。通常接收参数最多的初始化方法最终成为指定
 初始化函数。
 ***/

//重写dealloc方法,在对象的保留计数器值为0的时候objective-c会自动调用该方法以释放分配的资源,(千万不要手动调用)
- (void) dealloc
{
	NSLog(@"dealloc called bye bye");
	[super dealloc];
}
   
//重写description方法,构造自己的说明字符串,该方法着nslog()时自动调用
-(NSString *) description 
{
	
	//initWithFormat:便利初始化函数
	NSString *description=[[NSString alloc] initWithFormat:@"ssssssssss"];
	
	//把description字符串放入自动释放池,
	return [description autorelease];
}
 


@end

 //

//  RetainTrackCategory.h
//  MemoryManager
//
//  Created by 110 on 10-1-26.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import <Cocoa/Cocoa.h>

//         类名              类别命
@interface RetainTrack  (RetainTrackCategory) 
/*
 类别的声明中没有实例变量部分,只能声明消息
 */
-(NSString *) print;
@end

/**
 类别的局限性
 1:无法向类别中添加新的实例变量。类别没有位置容纳实例变量
 2:名称冲突,即类别中的方法与现有的方法重名。当发送方法名称冲突时,类别具有更高的优先级。你的类别方法将完全取代初始化方法,从而无法再使用初始方法。
 
 
 类别的作用
 1:使用类别分散实现
 在使用一个对象时,对象的方法是在接口中声明,在父类中声明还是在类别中声明并不重要。
 2:使用类别创建前向引用
 */
 /**
  委托(delegate),委托是一种对象,另一个对象会要求委托对象执行它的某些操作。
  委托和类别
  :委托强调类别的另一种应用:被发送给委托对象的方法可以声明为一个NSObject的类别,
  
  创建一个NSObject的类别成为“创建一个非正式协议”,使用非正式协议,你可以只实现你想要的方法。
  */

/***
 响应选择器
 什么所选择器:选择器只是一个方法名称,但它以objective-c运行时使用的特殊方法编码,以快速执行查询。你可以使用@selector()预编译指令指定选择器,其中方法名位于圆括号中。
 
 NSObject 提供了一个名为respondsToSelector:的方法,该方法询问对象以确定其是否能够响应某个特定的消息。
 
 if([car respondsToSelector:@selector(setEngine:)]{
  NSLog(@"ssssss");
 }
 
 选择器可以被传递,可以作为方法的参数使用,甚至可以作为实例变量存储
 
 */

 //

//  RetainTrackCategory.m
//  MemoryManager
//
//  Created by 110 on 10-1-26.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "RetainTrackCategory.h"

/**
 类别:是一种为现有的类添加新方法的方式。
 只有保证类别名称的唯一性,你可以向一个类添加任意多的类别
 
 */
@implementation RetainTrackCategory (RetainTrackCategory) 
-(NSString *) print{
	NSLog(@"pring-------");
}
@end
 
分享到:
评论

相关推荐

    C语言实现内存管理

    在编程世界中,C语言因其低级特性而被广泛用于系统级编程,其中包括内存管理。内存管理是程序设计中的核心部分,它涉及到如何有效地分配、使用和释放内存资源。本主题将深入探讨如何使用C语言来实现内存管理的关键...

    glibc内存管理ptmalloc源代码分析PDF

    分箱式内存管理是ptmalloc的另一个重要特性,它通过将内存块分类为不同的箱子来优化内存的分配和回收。small bins、large bins、unsorted bins和fast bins是ptmalloc中用于管理不同大小内存块的数据结构。 核心...

    内存,管理,控制,delphi的内存管理器

    Delphi作为一种流行的编程语言,提供了多种内存管理机制,帮助开发者高效地管理和使用内存资源。本文将深入探讨Delphi内存管理器的工作原理及其内部实现细节。 #### 二、Delphi内存管理器概述 在Delphi中,内存...

    深入理解linux虚拟内存管理(中+英)

    下面将详细介绍Linux虚拟内存管理的关键概念和技术。 首先,我们讨论一下虚拟内存的基本概念。在Linux系统中,每个进程都有自己的独立虚拟地址空间,包括代码区、数据区、堆区和栈区。这些区域在虚拟地址空间中分布...

    lwip内存管理_单片机内存管理_

    3. 选择内存分配策略:可以使用LwIP内置的内存分配函数,或者根据系统特性编写自己的内存管理函数。 4. 代码裁剪:移除不使用的协议模块和功能,减小程序体积。 5. 测试和优化:确保裁剪后的LwIP在目标平台上稳定...

    C++ 内存管理算法和实现.

    C++ 是一种强大的编程语言,其灵活性和性能深受程序员喜爱,但同时也要求程序员对内存管理有深入的理解。本文将详细探讨C++中的内存管理算法及其实现。 首先,我们需要理解C++中的内存分为哪几个区域。主要有栈...

    Linux内存管理 vs. Windows 2000内存管理

    Linux和Windows 2000操作系统在内存管理方面有显著的区别,这主要体现在它们的内存模型、页面替换算法、虚拟内存以及内存分配策略等方面。以下是对这些知识点的详细阐述: 1. **内存模型** - **Linux内存模型**:...

    VB-DLL和内存管理

    内存管理是计算机科学中的核心概念,它涉及到如何分配、使用和释放内存以确保程序高效、稳定地运行。在VB-DLL中,理解内存管理至关重要,因为它直接影响到DLL的性能和稳定性。 VB-DLL中的内存管理主要涉及以下几个...

    内存管理 嵌入式 C

    `Mymalloc.c`和`Mymalloc.h`这两个文件可能包含了自定义内存管理函数的实现和声明。常见的内存管理函数包括`malloc()`、`calloc()`、`realloc()`和`free()`。在C语言中,这些函数用于动态分配和释放内存,但在嵌入式...

    C内存管理算法和实现

    在编程领域,内存管理是至关重要的一个环节,尤其是在C语言这样的低级编程语言中,程序员需要手动进行内存的分配和释放。本主题主要探讨的是C语言中的内存管理算法及其实现,特别是堆和栈的管理以及内存回收策略。 ...

    Delphi快速内存管理 ScaleMM

    《Delphi快速内存管理:揭秘ScaleMM》 在Delphi编程世界中,内存管理...通过理解并利用ScaleMM的特性,开发者可以构建更加高效、稳定的应用程序,同时,它的开源属性也为我们提供了深入学习和改进内存管理策略的机会。

    Oracle中自动共享内存管理特性深入分析

    一个 Oracle 例程的系统全局区域 (SGA) 包含几个内存区域(包括缓冲高速缓存、共享池、Java 池、大型池和重做日志缓冲)。这些池在操作系统的内存空间中占据了固定的内存数;它们的大小由 DBA 在初始化参数文件中...

    内存管理深入剖析教程

    本教程将深入剖析内存管理的本质,旨在帮助开发者更好地理解和掌握这一关键技能。 内存管理主要涉及以下几个方面: 1. **内存区域划分**:在C语言中,内存分为栈区、堆区、静态存储区和常量存储区。栈区用于存放...

    linux内存管理结构图

    Linux内存管理是操作系统的核心部分,它负责有效地分配和回收系统中的物理和虚拟内存。在Linux中,内存被划分为多个区域(Zone)和节点(Node),以优化内存的使用和性能。以下是对这些概念的详细解释: 1. **节点...

    C++内存管理小结(内存控制)

    ### C++内存管理小结(内存控制) #### 内存管理的重要性 ...在实际开发中,结合使用智能指针和RAII(Resource Acquisition Is Initialization)原则等现代C++特性,可以进一步简化内存管理,减少出错的可能性。

    单片机内存管理malloc源码提供内存回收策列

    本文将深入探讨标题提及的“单片机内存管理malloc源码”及其内存分配策略,包括首次适应(First Fit)和最佳适应(Best Fit)方法,以及内存回收中的碎片整理功能。 首先,malloc函数是C语言中用于动态内存分配的...

    sql内存管理机制

    总结来说,SQL SERVER 2000的内存管理涉及到虚拟内存的分配、提交和释放,以及与Windows操作系统的紧密协作。理解这些机制可以帮助开发者做出更明智的决策,以优化数据库性能,减少内存争抢,提升整体系统效率。在...

Global site tag (gtag.js) - Google Analytics