国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Objective-C知識總結(3)

2019-11-14 18:38:06
字體:
來源:轉載
供稿:網友

手動內存管理MRC

首先介紹一下引用計數器:用來保存當前對象有幾個東西在使用它(數字)

引用計數器的作用:用來判斷對象是否應該回收內存空間(如果對象不等于nil,當引用計數器為0,此時要回收對象的內存空間)

引用計數器的操作:

  • retain    使得引用計數器+1

  • release   使的引用計數器-1

  • retainCount  得到引用計數器的值

如果一個對象被釋放的時候,會調用該對象的dealloc方法

注意:

  • dealloc方法是NSObject 的,一般我們要重寫dealloc方法
  • 在dealloc 方法的內部,要調用 [super dealloc];

內存管理的范圍:

  • 所有的集成了NSObject的對象的內存管理

  • 基本數據類型(int double float char struct enum )的數據內存不需要我們進行管理

內存管理的原則:

  1. 如果對象有人使用,就不應該回收  

    如果你想使用這個對象,應該讓這個對象 retain一次  

    如果你不想使用這個對象了,應該讓這個對象 relase一次

  2. 誰創建 誰release

  3. 誰 retain 誰 release

內存管理研究的內容:

  1. 野指針:

      1)定義的指針變量沒有初始化     2)指向的空間已經被釋放

  2. 內存泄露:

    {             Person *p  = [Person new];              }/*             p 棧區             [Person new];  堆區              如果棧區的p已經釋放了,而堆區的空間還沒有釋放,堆區的空間就被泄露了*/

set方法內存管理

//  Dog* _dog; //  對于對象作為另外一個類的實例變量 - (void)setDog:(Dog*)dog {  //  判斷對象是否是原對象        if(_dog != dog) {            //2) release舊值           [_dog release];             // retain 新的值,并且賦值給實例變量           _dog = [dog retain];        }    }

循環retain問題

循環的retain 會導致兩個對象都會內存泄露

防止方法:

  1. 讓某個對象多釋放一次 (注意順序)

  2. 一端使用 assign   一端使用retain(推薦使用)

NSString類的內存管理問題

#import <Foundation/Foundation.h>int main(int argc, const char * argv[]) {    @autoreleasepool {                //定義字符串        //字符串的常量池,        //如果你需要的字符串在常量池中已經存在了,不會分配內存空間        //使用字符串的時候,        // @"abc"  stringWithString    alloc initWithString  都在常量區//                //0x100001030 小        NSString *str1 = @"abc";   //@"abc" 字符串的常量        NSString *str3 = [NSString stringWithString:@"abc"];   //常量區        NSString *str5 = [[NSString alloc] initWithString:@"abc"]; //也在常量區        NSString *str6 = [[NSString alloc] init];//常量區        str6 = @"abc";                //0x100202030 大        //如果在常量區 str2  str4 地址應該是一樣的        //實際上不一樣的,所以 str2 str4都在堆區        NSString *str2 = [NSString stringWithFormat:@"abc"];   //不是在棧區,在堆區        NSString *str4 = [[NSString alloc] initWithFormat:@"abc"];//不是在棧區,在堆區                        //0x7fff5fbff764        int a = 10;  //棧區                NSLog(@"str1 = %@,%p,%lu",str1,str1,str1.retainCount);        NSLog(@"str2 = %@,%p,%lu",str2,str2,str2.retainCount);        NSLog(@"str3 = %@,%p,%lu",str3,str3,str3.retainCount);        NSLog(@"str4 = %@,%p,%lu",str4,str4,str4.retainCount);        NSLog(@"str5 = %@,%p,%lu",str5,str5,str5.retainCount);        NSLog(@"str6 = %@,%p,%lu",str6,str6,str6.retainCount);        NSLog(@"a = %p",&a);                    }    return 0;}

自動釋放池 :特殊的棧結構

特點: 

  • 對象可以加入到自動釋放池中
  • 自動釋放池結束的時候,會給池中的對象發送一條 release消息

自動釋放池的使用:

  1. 創建自動釋放池
      @autoreleasepool {      }

     2.  加入自動釋放池

/*  在自動釋放池中  [對象  autorelease];*/

模擬一個Person類 類中有個一個對象方法- (void)run;

#import <Foundation/Foundation.h>#import "Person.h"int main(int argc, const char * argv[]) {    //1 創建自動釋放池    Person *p = [Person new];  // p  1    @autoreleasepool {//自動釋放池開始                [p run];         NSLog(@"%lu",p.retainCount); // 1                // [p autorelease] 把對象p加入到自動釋放池中        // 注意:加入到自動釋放池中以后, 引用計數不會變化        [p autorelease];  //加入自動釋放池,        NSLog(@"%lu",p.retainCount); // 1                [p run];            }//自動釋放池結束   [p release];    [p run];    return 0;}

 我們可以給Person添加一個類方法,讓其創建完對象就加入到自動釋放池中

+(instancetype)person{    //Person person  ---> Person    //Stduent person ----> Student    //創建對象    return [[[self alloc] init] autorelease];  // 返回的時對象的空間    // 能夠幫我們把對象給加入到自動釋放池}

 

     

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 广安市| 青浦区| 江油市| 双桥区| 平和县| 龙里县| 惠来县| 柯坪县| 万载县| 长乐市| 隆尧县| 乌鲁木齐市| 堆龙德庆县| 华阴市| 东乡| 淮阳县| 剑川县| 宝清县| 紫金县| 乌什县| 敖汉旗| 呼和浩特市| 永济市| 远安县| 普宁市| 无棣县| 会昌县| 内乡县| 秦皇岛市| 化德县| 榆树市| 江油市| 鸡泽县| 西安市| 兴海县| 界首市| 华容县| 千阳县| 广河县| 沽源县| 招远市|