• OC:属性的内部实现原理、dealloc内释放实例变量、便利构造器方法的实现原理、collection的内存管理


    代码:

    //
    //  main.m
    #import <Foundation/Foundation.h>
    #import "Person.h"
    #import "SingleDog.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            //改为工程为 非ARC 就是 MRC机制
            Person * per = [[Person alloc]initWithName:@"lee" age:16];
            NSString * name = [[NSString alloc]initWithFormat:@"Li"];//为对象改名字
            [per setName:name];
            [per setName:name];//问题(多赋值了一次) B
            [name release];//对应创建时候的 alloc 进行一次释放 E
            NSLog(@"%@",[per name]);//这里出现野指针 A
            NSString * na  = @"Zhang";
            [per setName:na];//C
        }
    
    /**/
        //自动释放池 用来存声明为 autorelease 的对象
        //当自动释放池销毁时,会往池中的每一个对象(调用 autorelease 方法 的对象)(先进后出)发送一个 release 消息
        @autoreleasepool {
            Person * pp = [[Person alloc]init];
            Person * pp2 = [[Person alloc]init];
            Person * pp3 = [[Person alloc]init];
    //        [p autorelease];
            @autoreleasepool {
                //栈 ( LIFO 后进先出 )
                //队列 先进先出( FIFO )
                //自动释放池以 栈( LIFO ) 的方式来管理池中的对象
                [pp retain];
                [pp2 retain];
                [pp3 retain];
                [pp autorelease];//对象调用 autorelease 方法,当自动释放池销毁的时候,引用计数器减1
                [pp2 autorelease];
                [pp3 autorelease];
            }
            NSLog(@"内部释放池销毁");
        }
            NSLog(@"外部释放池销毁");
    
        
        
    /*
            @autoreleasepool {
                //面试题
    //            for (long  i = 0; i < 1000000000; i++) {
    //                Person * pp = [[Person alloc]init];
    //                [pp autorelease];
    //            }
                //解决内存不足问题办法
                for (long i = 0; i <10000000000000; i++) {
                    @autoreleasepool {
                         Person * pp = [[Person alloc]init];
                        [pp retain];
                        [pp autorelease];
                    }
                }
           }
    */
        
        //copy
        // copy 有深拷贝 和 浅拷贝 之分
        //浅拷贝 只拷贝地址
        //深拷贝 拷贝内容 新创建出一个对象
        @autoreleasepool {
            //
            Person * one = [[Person alloc]initWithName:@"first" age:12];
            Person * two = [one copy];//直接 copy 一份
            //如果是同一个地址就是 浅拷贝 如果不是同一个地址就是 深拷贝
            NSLog(@"one %p",one);
            NSLog(@"two %p",two);
            NSLog(@"%lu  %lu",one.retainCount,two.retainCount);
        }
        
        //容器 (collection)的内存管理
        //1.当集合中添加对象元素时,集合会对每一个元素做一次 retain 的操作,使其引用计数加 1
        //2.当集合中移除某个元素的时候,集合会对其做一次 release 操作,使其引用计数器减 1
        //3.当容器对象销毁的时候,会向容器内部的每一个元素的发送一个release 消息,使其引用计数器减 1
        NSMutableArray * arr = [[NSMutableArray alloc]initWithCapacity:3];
        Person * p1 = [[Person alloc]init];
        Person * p2 = [[Person alloc]init];
        Person * p3 = [[Person alloc]init];
        [arr addObject:p1];
        [arr addObject:p2];
        [arr addObject:p3];
        for (Person * per in arr) {
            NSLog(@"----%lu",per.retainCount);
        }
        [arr removeObject:p1];//这里我们移除一个对象 p1
        NSLog(@"--%lu",p1.retainCount);
        [arr removeAllObjects];//这里把所有的都释放掉
        for (Person * per in arr) {
            NSLog(@"--000--%lu",per.retainCount);
        }
        [arr release];//3
        p3 = nil;
        NSLog(@"%lu",p3.retainCount);
        
        //便利构造器的内部内存管理
        Person * person = [Person personWithName:@"wang" age:21];
        person.name = @"Hei";
        
        return 0;
    }
    View Code main.m
    //
    //  Person.h
    
    #import <Foundation/Foundation.h>
    #import "SingleDog.h"
    
    @interface Person : NSObject<NSCopying>
    //{
    ////    NSString * name; //只有在alloc 后才是一个对象,现在还是一个指针,是在栈区 D
    //}
    //属性的作用 自动生成setter getter
    //copy只用于那些遵循 NSCopying协议的 ,retain 让计数器加1,  引用计数一定是对象,一定是在堆区
    // assign 因为他不是对象,所以不用内存管理
    @property (nonatomic,retain)NSString * name;
    @property (nonatomic,assign)NSInteger age;
    @property (nonatomic,retain) SingleDog * dog;
    - (id)initWithName:(NSString *)name
                   age:(NSInteger)age;
    - (void)test;
    //便利构造器(的内存处理)
    + (Person *)personWithName:(NSString *)name
                           age:(NSInteger)age;
    @end
    View Code person.h
    //
    //  Person.m
    
    #import "Person.h"
    
    @implementation Person
    
    
    -(id)copyWithZone:(NSZone *)zone{
        Person * per = [[Person allocWithZone:zone]init];//深拷贝copy
        per.name = self.name;
        per.age = self.age;
        per.dog = self.dog;
        return per;
    }
    @synthesize dog = _dog;//要自己写setter getter
    -(void)setDog:(SingleDog *)dog{
        if (_dog != dog) {
            [_dog release];
            _dog = [dog retain];//以上是内存处理
        }
        //这里可以设置自己设置的属性
    }
    
    
    @synthesize name = _name;//这是我们要重新写setter getter的方法的时候,要用到,如果不需要重新写的话,就不用写这个方法
    -(void)setNAme:(NSString *)name{
    //    _name = name ;
    //    [_name release];
        if (_name != name) {//(这里是新对象) 判断是不是新的对象 B
            [_name release];//。D (如果第一次初始化的时候,_name)如果还没有 E(原有的对象还没有释放) 保持对新的对象的所有权 C
            //对一个字符串 多次release 不会 crash 因为他不在堆区 初次初始化的时候 name = nil,在栈区
            _name  = [name retain];//(让新对象引用计数器加1)(retain 保留所有权)解决野指针问题 A  该处的 retain 需要下面dealloc  // retain 只是引用了对象的地址   copy 是拷贝对象(这里需要在学习) 如果对象的语义是 copy 这里就要写成_name  = [name copy];
        }
    //    _name  = [name retain];//(retain 保留所有权)解决野指针问题 A
    }
    -(NSString *)name{
        return [_name retain];
    //    return [_name copy];如果数据类型 为copy
    //    _age = age; 基本的数据类型 直接的赋值操作 语义为 assign
    }
    
    - (void)setAge:(NSInteger)age{
        _age = age;
    }
    
    - (id)initWithName:(NSString *)name
                   age:(NSInteger)age{
        self = [super init];//这里为什么这样写
        if (self) {
    //        _name = name;  没有走 setter 方法
    //        _age = age;
            self.name = name; 
            self.age = age;
        }
        return self;
    }
    //对象在销毁的时候会自动调用该方法(注意我们不能用对象直接去调用该方法)
    -(void)dealloc{//一般对应于 语义属性为 retain copy 的,  注意:——》assign 的不会调用该方法(是直接的赋值 取值)
        //在 MRC 下才要写这些方法 如果在 ARC 下就打不出来这些方法。  在dealloc 中需要对该类中语义属性为 retain copy 的属性生成的实例变量进行 release 操作
    //    [_name release];//与下面的作用是一样的(解决对象没有及时释放掉的)(这个方法建议不用)
        self.name = nil;//在release 的时候 又把 指针置为 nil 防止出现野指针 好处是 内部调用了setter 方法 在 setter 方法内部进行了实例变量的 release 一次操作,同时将对象指向 nil
        self.dog = nil;//处理狗的对象 所有的对象(有alloc retain的对象)在这里都要被销毁
        [super dealloc ];//调用父类的方法将对象的空间真正回收
    }
    
    //便利构造器(的内存处理)
    +(Person * )personWithName:(NSString *)name
                           age:(NSInteger)age{
        Person * per = [[Person alloc]initWithName:name age:age];
    //    [per release]; return per; //就相当于反回了一个野指针
    //    return  per; [per release];//return 后面的代码不会执行
        return [per autorelease];//既可以避免野指针,同时还可以避免内存泄露。。系统的内部的便利构造器的内存处理也是一样的
    }
    @end
    View Code person.m
    //
    //  Student.h
    
    #import "Person.h"
    
    @interface Student : Person
    @property (nonatomic,readwrite,assign)NSInteger stuNum;
    @property(nonatomic,readwrite,copy)NSString * school;
    @property(nonatomic,readwrite,copy)NSString *address;
    
    //初始化
    -(id)initWithName:(NSString *)name
                    age:(NSInteger)age
    //                dog:(SingleDog*)dog
                 stunum:(NSInteger)stunum
                 school:(NSString *)school
                address:(NSString *)address;
    - (void)dealloc;
    +(Student *)studentWithName:(NSString *)name
                           age:(NSInteger)age
                        stunum:(NSInteger)stunum
                        school:(NSString *)school
                        address:(NSString *)address;
    @end
    View Code student.h
    //
    //  Student.m
    
    #import "Student.h"
    
    @implementation Student
    
    -(id)initWithName:(NSString *)name
                    age:(NSInteger)age
    //                dog:(SingleDog*)dog
                 stunum:(NSInteger)stunum
                 school:(NSString *)school
                address:(NSString *)address{
        self = [super init];//一般进行初始化设置
        if (self) {
            self.name = name;
            self.age =age;
            self.stuNum = stunum;
            self.school = school;
            self.address = address;
        }
        return self;
    }
    - (void)dealloc{
        self.name = nil;
        self.school = nil;
        self.address = nil;
        [super dealloc];
    }
    
    +(Student *)studentWithName:(NSString *)name
                            age:(NSInteger)age
                         stunum:(NSInteger)stunum
                         school:(NSString *)school
                        address:(NSString *)address{
        Student * stu = [[Student alloc]initWithName:name age:age stunum:stunum school:school address:address];
        return stu;
    }
    @end
    View Code student.m
    //
    //  SingleDog.h
    
    #import <Foundation/Foundation.h>
    
    @interface SingleDog : NSObject
    
    @end
    View Code singleDog.h 
    //
    //  SingleDog.m
    
    #import "SingleDog.h"
    
    @implementation SingleDog
    
    @end
    View Code singleDog.h 


    //
    //  main.m
    //  Practice
    
    #import <Foundation/Foundation.h>
    #import "Man.h"
    #import "Woman.h"
    #import "Family.h"
    #import "Child.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // OC比较综合的一个练习 (本工程手动为  MRC)
            Man * husband = [[Man alloc]initWithName:@"Lee" gender:@"man" age:22];
            Woman * wife = [[Woman alloc]init];
            wife.age = 21;
            wife.gender = @"woman";
            husband.wife = wife;//为丈夫设置一个媳妇
            Family * family = [[Family alloc]init];
            [family sayHi:husband];
            [family sayHi:wife];
            //多态,对一个方法传进去不同的值,反馈的结果不一样 对同一个方法的响应 回复的方法不一样
            Child * ch = [[Child alloc]init];
            /*
            ch.delegate = husband;
            ch.delegate = wife;
            [husband release];// 孩子代理的语义属性问题 assign (避免代理的循环引用问题)
            */
            //设置代理人
            ch.delegate = husband;
            [ch toGo];
            ch.delegate = wife;//这里把上面的代理 husband 覆盖了
            [ch toGo];
            //一般一个类里设置一个代理
        }
        return 0;
    }
    View Code mian.m
    //
    //  Person.h
    //  Practice
    
    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    @property(nonatomic,retain)NSString *name;
    @property(nonatomic,retain)NSString *gender;
    @property(nonatomic,assign)NSInteger age;
    
    - (id)initWithName:(NSString *)name
                gender:(NSString *)gender
                   age:(NSInteger)age;
    
    - (void)dealloc;
    @end
    ------------------------------------------------
    View Code person.h
    //
    //  Person.m
    //  Practice
    
    #import "Person.h"
    
    @implementation Person
    
    - (id)initWithName:(NSString *)name
                gender:(NSString *)gender
                   age:(NSInteger)age{
        self = [super init];
        if (self) {
            self.name = name;
            self.age = age;
            self.gender = gender;
        }
        return self;
    }
    
    - (void)dealloc{
        self.name = nil;
        self.gender = nil;
        [super dealloc];
    }
    @end
    View Code person.m
    //
    //  Family.h
    //  Practice
    
    #import <Foundation/Foundation.h>
    #import "Person.h"
    @class Man;
    @class Woman;
    @class Child;
    
    @interface Family : NSObject
    
    - (void)sayHi:(Person * )per;//自我介绍方法
    @end
    View Code family.h
    //
    //  Family.m
    //  Practice
    
    #import "Family.h"
    #import "Man.h"
    #import "Woman.h"
    #import "Child.h"
    
    @implementation Family
    
    - (void)sayHi:(Person * )per{
        NSLog(@"my name is %@  age is %ld gender is %@",per.name,per.age,per.gender);
    }//自我介绍方法
    @end
    View Code family.m
    //
    //  Man.h
    //  Practice
    //
    //
    #import "Person.h"
    @class Woman;
    //@class Child;
    #import "Child.h"
    
    @interface Man : Person<TakecareDelegate>//3代理人遵循协议
    //son wife
    @property(nonatomic,retain)Child *son;
    @property(nonatomic,retain)Woman *wife;
    #pragma --------delegate-----
    
    - (void)playWithScore;
    #pragma --内存释放--
    - (void)dealloc;
    @end
    View Code man.h
    //
    //  Man.m
    //  Practice
    
    #import "Man.h"
    #import "Woman.h"
    #import "Child.h"
    
    @implementation Man
    
    @synthesize wife = _wife, son = _son;
    
    //setter getter
    - (void)setWife:(Woman *)wife{
        if (_wife != wife) {
            [_wife release];
            _wife = [wife retain];
          // _wife = [_wife retain];//这是出错的方法,相当于_wife自己没有任何操作
        }
        _wife.name = @"Anni";//在这里做一些额外的操作
        NSLog(@"my wife is %@",_wife.name);
    }
    - (Woman *)wife{
        return [[_wife retain]autorelease];
    }
    
    - (void)setSon:(Child *)son{
        if (_son != son) {
            [_son release];
            _son = [son retain];
        }
    }
    - (Child *)son{
        return [[_son retain]autorelease];
    }
    
    #pragma -----delegate----
    
    - (void)playWithScore{
         NSLog(@"踢足球");
    }
    #pragma ----内存释放-----
    - (void)dealloc{
        self.wife = nil;
        self.son = nil;
        [super dealloc];
    }
    @end
    View Code man.m
    //
    //  Woman.h
    //  Practice
    
    #import "Person.h"
    @class Man;
    //@class Child;
    #import "Child.h"
    
    @interface Woman : Person<TakecareDelegate>//3代理人遵循协议
    //husband child
    @property(nonatomic,retain)Man *husband;
    @property(nonatomic,retain)Child *son;
    #pragma -------delegate-----
    - (void)getMeToSchool;
    #pragma ---内存释放-----
    -(void)dealloc;
    @end
    View Code woman.h
    //
    //  Woman.m
    //  Practice
    
    #import "Woman.h"
    #import "Man.h"
    #import "Child.h"
    
    @implementation Woman
    #pragma ----delegate----
    - (void)getMeToSchool{
        NSLog(@"上学去");
    }
    #pragma ---内存释放----
    -(void)dealloc{
        self.son = nil;
        self.husband = nil;
        [super self];
    }
    @end
    View Code woman.m
    //
    //  Child.h
    
    #import "Person.h"
    @class Man;
    @class Woman;
    
    
    //协议 (1)制定协议
    @protocol TakecareDelegate <NSObject>
    
    - (void)getMeToSchool;
    - (void)playWithScore;
    
    @end
    
    @interface Child : Person
    //father mother
    @property(nonatomic,retain)Man *father;
    @property(nonatomic,retain)Woman *mother;
    //协议 (2) 设置代理人  设置代理的语义属性 assign  主要是避免循环引用问题 (*****如果设置为 retain 在对应的 dealloc 方法里面)
    @property(nonatomic,assign)id<TakecareDelegate>delegate;
    
    - (void)toGo;
    
    #pragma ---内存管理----
    - (void)dealloc;
    @end
    View Code child.h
    //
    //  Child.m
    //  Practice
    
    #import "Child.h"
    #import "Man.h"
    #import "Woman.h"
    
    @implementation Child
    
    //通知代理去执行协议方法
    - (void)toGo{
        //下面是代理是父亲或者母亲单方(两个协议都执行了)
    //    if (_delegate) {
    //        [_delegate getMeToSchool];
    //        [_delegate playWithScore];
    //    }
        
        //下面是一个代理响应了某个方法,该代理就会去执行相对应的方法 (父母都为代理,分别执行一个协议)
        //了解  respondsToSelector 方法(返回的是一个bool 数值) (看API 文档)
        if (_delegate && [_delegate respondsToSelector:@selector(getMeToSchool)]) {//判断如果实现了 @selector(某方法) 下面就执行 某方法
            [_delegate getMeToSchool];
        }
        if (_delegate && [_delegate respondsToSelector:@selector(playWithScore)]) {
            [_delegate playWithScore];
        }
    }
    #pragma -----内存管理------
    - (void)dealloc{
        self.mother = nil;
        self.father = nil;
        [super dealloc];
    }
    @end
    View Code child.m

    Objective-C概述

    Objective-C简称OC, 扩充自C语言的面向对象编程语言。是OS X 和IOS操作系统的主要编程语言。一种面向对象的计算机语言。开发环境和类库叫“NEXTSTEP”,1996年,把NEXTSTEP/OPENSTEP用于Mac OS操作系统开发。它的版本和开发环境叫Cocoa,使用Objective - C作为基础语言,开发环境Xcode和interface Builder.
    OC语言的特点:
    C语言的超集,允许在OC中使用C语言源代码,编译器兼容C语言程序。
    具备完善的面向对象特性。
    包含一个运行时系统。
    类库丰富。
    面向对象编程:

    面向过程

    面向对象

    特点

    分析解决问题的步骤,实现函数,依次调用函数

    分析某问题需要参与的对象,各对象的作用,多个对象协作完成任务

    侧重点

    实现功能

    对象的设计

    语言举例

    C语言

    OCC++Java

    基本介绍:面向对象编程 OOP(Object Oriented Programming )
                     面向对象语言 : C++、 Java、 C#
                     概念: 对象、类、封装、继承、多态等等
    面向对象3大特征:封装、继承、多态。
    封装的思想:”麻烦自己,方便别人”。
    两种编程思想:
    面向对象设计具有良好的可扩展性、可重用性。
    类和对象
    类:具有相同特征和行为的事物的抽象。
    对象:对象就是类的实例,类的具体表现。生活中的万物都是对象。
    类和对象是面向对象的核心。对象是类的实例。类是对象的类型。
    面向对象编程中使用对象完成程序。
    开发中:先定义类,再创建对象,然后使用对象。
    OC中类的定义
    定义类包含两部分:接口部分和实现部分。
            接口部分:对外声明类的特征和行为。(类似说明书)
            实现部分:对内实现行为。(内部的具体实现)
    接口部分标志:@interface...@end
    作用:声明类的实例变量和方法,即特征和行为。
    包含内容:类名、父类名、实例变量、方法等。
    实现部分标志:@implementation...@end
    作用:实现方法,即实现类的行为。
    类和文件
    类:@interface...@end      @implementation…@end
    文件:.h称为接口文件或头文件, .m称为实现文件。
    文件和类本质没有关系。
    创建对象
    类是模板,对象是具体表现,任何对象都要占用内存空间。
    创建对象分两步:分配内存空间和初始化。
    分配内存空间:根据类中声明的实例变量为对象分配内存,将所有实例变量置为默认值0,并返回首地址。
    初始化:为对象的实例变量设置初始值,
    +(id)alloc;+表示这个方法属于类,只能类执行。id返回值类型,表示任意类型的对象,即创建好的对象。
    -(id)init;-表示这个方法属于对象,只能对象执行。id返回值类型,表示初始化完成的对象。
    使用对象 
    指针存储对象的首地址,代指对象。OC中使用指针代指对象,进行操作。
    实例变量操作
    实例变量在初始化只做少量设置,后期还需要进行设置。
    实例变量区分可见度,共三种。 默认的可见度是@protected
             @public    (公有)    实例变量可在类的外部和内部操作
             @protected:(受保护)   实例变量只能在该类和其子类内操作
             @private:(私有的)  实例变量只能在该类内访问
    public修饰的实例变量,可以直接使用“->”访问。
    面向对象和面向过程是两种不同的编程思想,思考角度不同,前者以对象为中心,后者以事件为中心。
    类是对象的抽象,对象是类的体现。面向对象编程中,先创建出对应的类,再由类生成对象,进而完成我们的开发。
     
    方法
    OC中的方法分两种:类方法(只能类使用) 和 实例方法(只能对象使用)
    OC中方法采用消息发送机制:【receiver message】 给对象发送消息
    setter 、getter
    OC中,为实例变量赋值的方法称为setter(设置器)。读取实例变量值的方法称为getter(访问器)。
    设置器用来为实例变量赋值,访问器用来取实例变量的值。
    属性:@property (nonatomic,retain) NSString *name;
             @property (nonatomic,retain) NSString *gender;
             @property (nonatomic,assign) NSInteger age;
    相当于设置器与访问器,系统自动生成,直接调用即可,默认生成的实例变量可见度为私有。(retain assign copy)为语义属性,声明对象时使用retain copy,声明基本数据类型时用assign。 
    自定义初始化方法
    - (id)init 这个方法只能给实例变量设置默认值,不灵活。
    - (id)initWithName:自定义初始化方法,根据需求定义初始化方法。
    #import 导入头文件,
    #import””导入自定义类。#import<>导入;导入类库中的头文件。
    @class 告诉编译器@class后的字符串作为类名使用,并未导入类的接口内容,有效避免嵌套循环导入。
    继承
    继承的作用:既能保证类的完整,而且简化代码
    继承的特点:1.一个子类只能有一个父类;
                       2.继承是单向的(只允许单继承);
                       3.一个父类可有多个子类;
                       4.继承具有传递性;
                       5.继承时会继承父类所有的特征和行为。
    继承的内容:所有实例变量和方法。
    没有父类的类称为根类,OC中的根类是NSObject.
    super 
    编译器指令,并非对象。作用是:给super发消息,可以执行父类中实现的方法。
    初始化方法
    创建对象分两步:开辟空间、初始化。
    初始化方法的主要作用是:为某些实例变量赋初值
    初始化方法在对象的整个生命周期里只使用一次。
    完整的初始化方法:- (id)init
                                {
         做安全处理  //    self = [super init];  //执行父类中实现的init方法
                                     if(self){
                                    //初始化设置   
                                      }
                                      return self;
                                 }
    便利构造器 : 封装了对象创建过程
    Block的使用:
    Block允许嵌套定义,定义时最后加; 返回值可以省略。如:
    int(^sum)(int x, int y) = ^(int x, int y){
          return x + y;
    };
    挡在Block内部使用外部定义的局部变量时,如果变量没有被Block修饰,则在Block内部不能对它进行修改。若想修改,变量必须要有__block修饰。__block告诉编译器编译时在Block内部不要把外部变量当做常量使用,还是当做变量使用。如果在Block中访问全局变量,就不需要block修饰。
    NSString
    NSArray
    NSDictionary
    NSSet
    NSNumber
    NSDate
    类的扩展
    分类,类目,category为没有源代码的类添加方法(只添加方法,不添加实例变量)是扩展一个类的的功能的方式之一,为原有类扩展的方法会成为原类的一部分,使用即可。分类也分为.h(接口部分)以及.m(实现部分)。.h文件中填写声明的方法,.m文件中填写方法的实现。
    协议
    协议相当于任务清单,规定所要做的操作,谁服从协议,谁就要实现清单中的方法,所以协议只有.h文件,没有.m文件。协议要让类服从,服从完协议之后,要实现协议的方法。
    内存管理
    OC中采用引用计数机制管理内存。
    内存管理的基本原则:如果你对一个对象进行alloc retain copy 之后,你就拥有了该对象的所有权,就必须对它进行release或者autorelease。
    autorelease: 会将声明为autorelease的对象放到离他最近的自动释放池中,当自动释放池销毁时,会向池中的每一个对象发送一个release消息。
    release:立即释放
    当一个类的的对象引用计数为0时,系统会自动调用该类的dealloc方法来回收空间,该方法是由系统自动调用的,不用手动调用。
    当把一个对象放入一个集合中(数组、字典、集合)时,会将对象的引用计数加1,因为内部做了retain操作,当collection(数组 集合 字典)空间被回收时,它们会向容器的每一个元素都发送一个release消息(对应添加元素时的retain操作)。当从collection中移除一个元素时,会release该对象,引用计数减1.
     
    NSString *name; 它是在栈区的,并不是在堆区,现在的 name 是一个指针,因此在内存处理的时候,不要处理它,
  • 相关阅读:
    动手动脑
    加减乘除
    测试
    Java学习的第五十六天
    Java学习的第五十五天
    js判断一个时间是否在某一个时间段内
    js计算两个时间相差多少分钟
    js分钟转化为小时并且以某个数字进行递增
    关于Js debounce(防抖)函数和throttle(节流)小结
    webpack配置scss
  • 原文地址:https://www.cnblogs.com/benpaobadaniu/p/4753775.html
Copyright © 2020-2023  润新知