OC學習筆記總結(Block語法開始)


1, Block語法

定義:Block就是把一個匿名函數定義成一個變量,

語法格式: int (^)(int, int) Block類型

等號右邊給變量賦值,賦值是一個匿名函數

int (^myBlock)(int , int ) = ^int (int a, int b)

{

return a > b ? a : b;

};

int result = myBlock(10, 15);

NSLog(@”%d”, result);

//賦值的匿名函數返回值類型可以去掉 ^/*int*/(int a, int b)

//無參無返回值賦值匿名函數的時候,參數,返回值可以省略

void (^helloBlock)() = ^

{

NSLog(@”hello world”);

};

helloBlock();

 

API知識

//將字符串按某節點分割,取第一塊

NSString * (^splitString)(NSString *, NSString *) = ^(NSString * targetString, NSString * sepatorString)

{

return [[targetString  componentsSeparatedByString: sepatorString] firstObject];

};

NSString * string = splitString(@www.baidu.com, @”.”);

NSLog(@”%@”, string);

//逆序輸出數組

API: exchangeObjectAtIndex: (nsinteger)withObjectAtIndex: (nsinteger)

//將字符串數組拼接成字符串輸出

API: (NSString * targetstring) stringByAppendingString: (NSString * appendingstring);

//Block回調,

//Block用於排序

案例:在定義多個person對象后,對person對象進行年齡排序,定義一個不可變數組存放每個person對象,

Block語法: NSArray * newArray = [Array  SortedArrayUsingComparator: ^ NSComparisionResult(id obj1, id obj2)]

{

//強轉類型,在輸出的時候能快速定位到年齡

Person * person1 = (Person *)obj1;

Person * person2 = (Person *)obj2;

If ([person1 age] < [person2 age])

{

Return NSOrderedAscending;

}else if ([person1 age] > [person2 age])

{

return NSOrderedDescending;

}

return NSOrderedSame;

} ];

//默認情況下,Block中使用Block之外的變量,默認是只讀的,不可修改

//使用__block告訴編譯器,此變量在block中可以使用

//block類型的參數是用於回調時從里向外傳值(傳遞信息出去)

//block類型種的類型返回值用於從外向里傳值,(就是block回調完得到的結果)

 

多態:

//允許父類指針指向子類型對象

//屏蔽子類之間的差異,寫出更通用的代碼

//常見形式:

//參數多態和返回值多態

 

屬性

屬性的聲明: 屬性的類型  屬性名

@property  NSString  *  name;

//等價於聲明了一對方法,一個setter, 一個getter

//屬性的類型決定生成的setter方法的參數類型,getter方法的返回值類型

//屬性名決定生成的方法名是什么

屬性的特性:

第一大特性:

//readwrite 既生成setter, 也生成getter

//readonly 只生成 getter

//setter = , getter = , 用於控制生成setter方法和方法名

原子性特性:

//nonatomic 非原子性特性,不保證在多線程環境下訪問實例變量的安全性

//atomic 原子性特性(默認), 保證在多線程環境下訪問實例變量是安全的, 因為會加一把線程鎖

setter語義特性,控制生成的setter方法的內部實現細節

//assign (默認), 通常適用基本類型,setter方法中就是直接賦值

//retain, 適用於所有的對象類型,setter方法中會自動生成內存優化的代碼

//copy, 僅適用於接受過NSCoping協議的類的對象才適用

如果屬性的setter方法和getter方法同時重寫

//那么默認就不會幫你生成實例變量

//解決方案1:自己定義實例變量

//解決方案2:使用@synthesize

//@synthesize array = _array;

 

屬性的實現

//name = _name的含義,屬性name生成的setter和getter的實現中操作_name這個實例變量

//會先檢查有沒有該實例變量,如果沒有,會自動生成

//從iOS6.0之后@synthesize也可以不用寫了,編譯器自動生成

//但默認生成的屬性實現中是操作與屬性名同名加下划線的實例變量

//實例變量也可以不寫,不寫會自動生成,但生成的是私有的,子類不可以直接訪問

//父類里私有的實例變量,僅僅是不可以在子類中直接訪問

//子類創建對象的時候,這些父類私有實例變量也會被分配內存存儲,可以通過同父類繼承的setter或getter訪問

 

點語法

//點出現在等號左邊,等價於調用了setter方法

//點出現在等號右邊,等價於調用了getter方法

//沒有等號出現點,等價於getter

KVC(鍵值編碼)

時間類API使用

NSDate (date) 獲取當前時間

NSDateFormatter 把日期和字符串之間互轉

NSDateFormatter * formatter = [[NSDateFormatter alloc] init];

//設置轉換格式

formatter.dateFormat = @”yyyy-MM-dd EEEE hh:mm:ss a”;

//把日期對象轉成一個字符串

NSString * dateString = [formatter stringFromDate:date];

NSLog(@”%@”, dateString);

//假設這個是服務器端給我們返回的一個時間戳

//是一個表示時間的字符串

NSString * dateString = @”20150814061022”;

NSDateFormatter * formatter = [[NSDateFormatter alloc] init];

//字符串格式要跟返回的字符串格式一樣才能正確輸出

formatter.dateFormat = @”yyyyMMddhhmmss”;

//把日期字符串轉換成日期對象

NSDate * messageDate = [formatter dateFormString: dateString];

//獲取當前時間

NSDate * currentDate = [NSDate date];

//得到兩個時間之間相差的描述

NSTimeInterval = seconds = [currentDate timeIntervalSinceDate:messageDate];

NSLog(@”%.1f”, seconds);

后邊可以接跟時間長短的判斷,分成剛剛,幾分鍾前,幾小時前,幾天前,幾月幾號幾時幾分幾秒

得到一個從現在開始多少秒后的一個時間

NSDate * date = [NSDate dateWithTimeIntervalSinceNow:120];

NSLog(@”%@”, date);

得到從1970年到當前時間流逝的秒數

[date timeIntervalSince1970];

根據一個從1970年流逝的秒數得到一個時間對象

[NSDate dateWithTimeIntervalSince1970:seconds];

 

類目

//類目(分類, Categary): 給一個沒有原碼的類擴展方法

//類目只能擴展方法,不能擴展實例變量

//擴展的方法會成為原始類的一部分,和原始類中的方法一樣,級別相同,會被子類繼承

//                目標類    類目名

@interface NSString (SayHIMethod)

延展

//延展Extension, 幫一個類管理私有方法和私有變量

//OC中沒有絕對的”私有”方法,所謂私有方法就是在.m里有實現, .h里面沒有聲明

//延展就是一種特殊形式的類目,就是把類目的聲明寫到.m中,並且()里不加類目名

協議

//在 .h文件里創建

//協議中方法的參數的作用:用於讓代理調用時給它信息,供代理使用

//協議中方法返回值的作用:用於得到代理調用完方法的結果,讓委托方作出處理

//協議中定義的是一堆方法聲明,只有聲明,沒有實現

//一個類可以接受一到多個協議,接受了協議就必須實現協議里面的@required方法

//@required修飾的方法代表必須實現,@optional代表的方法是可選實現

//在父類后面加<協議名>表示遵守協議

內存管理

內存管理原則一:

//凡是出現alloc , retain, copy的地方,都要有對應的release或者autorelease與之對應,保證對象用完的時候可以被及時的銷毀

內存管理原則二:

//建類必備dealloc, 凡是有屬性被修飾成retain或copy的,都要dealloc里release, 防止外界使用屬性賦值之后最后一份釋放不掉

內存管理原則三:

//便利構造器內自帶autorelease

//問題1: 一個對象通過屬性賦完值之后,對象提前銷毀了,導致賦值完的屬性也用不了

//解決方案:賦值時加一個retain,那么會帶來問題2;

//問題2:每一次賦新值得時候,上次舊值留到內存里

//解決方案,每次賦新值前,先release一次舊值

//但是會產生問題3

//問題3: 多次給一個屬性賦同一個值,第二次賦值時對對象提前釋放

//解決方案:setter中加一個判斷,如果是同一個值,不做任何處理

//問題4: 最后一份創建的對象無法釋放

//解決方案:當班級對象被銷毀的時候,釋放學生的所有權,即重寫dealloc, release對象之后加[super dealloc]

自動釋放池

//工作原理:當對一個對象發送autorelease消息,就會把這個對象扔到離它最近的釋放池中,當這個池銷毀的時候會把池中所有管理的對象逐一發送一次release,進池出池的過程和棧一樣,遵循先進后出的原則,先進池的對象,池銷毀后release

copy

//當對一個對象發送copy消息,會自動調用copyWithZone:方法

//在copyWithZone:方法中,NSZone類型的參數記錄的原對象的內存結構信息,根據原對象內存結構信息,復制出一個副本

//再把原對象實例變量里面的內容賦值給拷貝出新對象的實例變量

//會讓拷貝出得新對象引用計數從0到1,原對象引用計數不變

字符串對象的內存管理

//常量區的字符串引用計數是一個無符號整形數的最大值,正常應使用%lu輸出,使用%d輸出會溢出,顯示-1

//無論對它release,還是retain,都無任何影響

dealloc

//對象引用計數變為0時,對象要被銷毀(內存回收), 這時會自動調用對象的dealloc方法

//dealloc方法永遠不要手動調用

數組字典的內存管理

//數組,字典,集合會對管理的對象引用計數加1

內存管理原則四:

//誰污染誰處理,凡是你自己alloc, retain, copy的,你就得有對應的,release或者autorelease, 不是干的,不要你管

//每次創建一個新字符串,產生的舊字符串會被存放在釋放池中,過多累積

//解決方案:添加自動釋放池

//防止對象被提前釋放,可以采用建空指針的方法避免

對象類型屬性兩個作用:

//1,方便在類的外部訪問類的實例變量

//2,幫你優化一份內存,在對象的整個生命周期中一直可以使用該實例變量

//在方法里創建對象,如果對象的地址保存在一個棧區指針里邊,那么出方法前,一定要release或者autorelease掉

//一旦有被retain, copy修飾的對象,就要重寫dealloc

//為了保證數組在一個方法中創建完,到另外一個方法中也能用

//通常把數組,定義為屬性,使用self.創建對象,因為此時相當於調用了setter方法, setter方法內部會retain一次,保證數組對象在所屬類的整個生命周期中都可以使用,這次retain, 在所屬類的dealloc中release一次

//使用數組是可以使用_array, 和使用self.array沒有區別, 因為是getter

//getter方法更安全的 寫法

return [[_array retain] autorelease];

//作用:延長對象的聲明周期


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM