iOS 基礎概念入門

一、面向對象

  • OO(Object Oriented) 面向對象
  • OOP(Object Oriented Programmint) 面向對象編程

面向過程編程以事件爲中心,程序圍繞事件,列出了事件的每個步驟,一步一步完成;
面向對象編程以事物爲中心,程序圍繞事物展開,完成事件只是一個任務;

二、面向對象三大特性

  1. 封裝:將現實世界中存在的某個客體的屬性與行爲綁定在一起,並放置在一外邏輯單元內;
  2. 繼承:子類自動共享父類數據結構和方法的機制;
  3. 多態:相同的操作或者函數,過程可作用於多種類型的對象上並能獲得不同的結果;
    objective-c是一種能夠完成複雜面向對象編程的簡單的計算機語言,通過提供用於定義類和方法的語法,它擴展了標準的ANSI C程序設計語言。還提供類和接口(任何類都可採用)的動態擴展;

三、類對象的初始化
爲了分配對象,需要發送alloc消息給該消息的類,來獲取一個原始(未初始化)的實例,分配對象時,oc運行時會從應用程序的虛擬內存爲對象分配足夠的內存,除分配內存外,運行時在分配期間還會將所有實例變量設定爲0。
分配原始實例後,必須要對它初始化,初始化的過程將一個對象的初始狀態(即實例變量和屬性)設定爲合理的值並返回對象,初始化的目的在於返回可用的對象,原始初始化init會將內存中的所有對象清0;

1.自定義初始化方法:
創建對象分兩步:分配空間和初始化,初始化的作用就是爲對象賦初始值,初始化方法通常以init開頭;

  • super:將消息發送給父類對象;
  • self:將消息發送給本對象(self始終代表接收消息的對象);
  • [super init]就是將init消息發送給父類對象;

2.指定初始化方法:
通常情況下是指能夠賦值最多的方法;

四、類的屬性及成員變量
屬性是一組設置器與訪問器,與類相似,屬性需要聲明和實現;
屬性的聲明寫在類的.h文件中:

@property int age; 

上面的代碼實際上相當於聲明瞭兩個方法

-(void)setAge:(int)age;
-(int)age;

屬性的實現寫在類的.m文件中:

@synthesize age = _age;

該語句的作用是使setAge、以及age方法都是在操作實例變量_age,如果類對象沒有_age實例變量,編譯器會自動聲明一個實例變量_age,並且屬性名是age;

相當於實現了兩個方法:


-(void)setAge:(int)age { _age = age; }
-(int)age{ return _age; }

屬性也可以設置特性:
1.讀寫特性:

readwrite|readonly
getter = 方法名 // 指定訪問器的方法名
setter = 方法名 // 指定設置器的方法名

2.原子性特性:

nonatomic // 非原子性,不保證多線程安全
atomic // 原子性,多線程訪問時較安全

3.setter/getter語義特性:

assign // 直接賦值(適用於基本數據類型int,float,struct)
retain // 賦值時做內存優化 (適用於對象類型)
copy // 複製一個副本 (適用於特殊的對象類型)

屬性和實例變量是不同的,前者是一組方法,後者是一個變量,定義屬性使用@property和@synthesize;

對於屬性的特性定義:基本數據類型使用assign,對象類型使用retain,實現了NSCopying協議的對象使用copy。

五、內存管理
OC採用”引用計數機制”(retainCount)管理對象所佔用的內存;
在OC語言中,NSObject類及子類的實例對象包含一個整形屬性,用來統計當前的引用計數;
實例對象的生命週期:起始於alloc,終止於dealloc;
通過對類發送alloc消息,獲得的實例對象的引用計數賦值爲1,當實例對象的引用計數爲0時,自動對該對象發送dealloc消息;

  • copy 製造一個副本,將副本的引用計算賦值爲1,並且擁有副本的所有權
  • retain 對象引用計數+1,並擁有對象所有權
  • release 對象引用計數-1,並放棄對象所有權
  • autorelease 未來某個時間對象引用計數-1,並放棄對象所有權;

指針變量和對象區別聯繫:
對象是放在堆裏面的,而指針變量是放在棧裏面的,唯一的關係是指針變量存的是對象的地址;

非ARC下設置對象的實例屬性

@property(retain, nonatomic) Student *stu;
-(void)setStu:(Student *)stu
{
    [stu retain]; // 擁有對象所有權
    [_stu release]; // release 之前的_stu,放棄所有權
    _stu = stu;
}

dealloc方法在對象引用計數爲0的時候自動被調用,主要用於釋放自身所佔有的資源,永遠不要手動調用dealloc;

-(void)dealloc
{
    [_stu release];
    [super dealloc];
}

六、自動釋放池
1.使用NSAutoreleasePool類
當創建的對象未來某個時候銷燬時,可以用對象的autorelease方法;對象會將所有權交給最近的NSAutoreleasePool對對象,當池對象drain或者release時,會逐一對池內的對象發送release消,儘量不要使用autorelease,而是使用release;

2.早期版本的自動釋放池

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
// TODO
Student *stu = ...;
[stu autorelease];
[pool release];

3.現版本的創建

@autorelesepool{
    Student *stu = ...;
    [stu autorelease]; // 將所有權控制交給pool,stu不用手動release;
}

4.便利構造器

+(id) studentWithName:(NSString *)name
{
    Student *stu = ...;
    return [stu autorelese];
}

內存管理原則:
(1).凡是使用alloc、retain、copy的地方,就要有release或者autorelease與之對應,他們要配對使用;
(2).屬性爲retain或者copy的話,需要在類的dealloc中釋放這個屬性;
(3).便利構造器本身應該包含autorelease(系統框架中的便利構造器已經包含autorelease,所以使用便利構造器獲取得的對象不需要release);
(4).一定不要釋放沒有所有權的對象,不要手動調用dealloc;

在dealloc中輸出NSLog,看dealloc是否執行來判斷對象是否釋放;
關於內存管理,在最新版本的OC中,已經不需要我們手動去release了。

內存檢測工具:
Analyze 內存靜態分析(編譯期)
leaks(Instruments) 內存泄露檢測工具(運行期)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章