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

首頁 > 系統 > iOS > 正文

IOS學習筆記之Object-C(一)

2019-11-07 23:53:39
字體:
來源:轉載
供稿:網友

++ 概述 ++ 目前來說,Objective-C(簡稱OC)是iOS開發的核心語言,在開發過程中也會配合著使用C語言、C++,OC主要負責UI界面,C語言、C++可用于圖形處理。 * 基于C語言:C語言是一門面向過程的語言,OC是在C語言的基礎上,增加了一層最小的面向對象語法,為什么說是最小的面向對象語法呢?因為OC把一些比較復雜的面向對象語法都去掉了,剩下的都是面向對象的精華,因此OC是一門面向對象的語言,而且會比C++簡單很多。因為OC是基于C語言的,所以完全兼容C語言,也就是說我們在開發iOS程序過程中,可以在OC代碼中混入C語言代碼,甚至是C++代碼。

語法概述: 1.沒有包名(命名空間)的概念


java中,為了防止兩個類名相同的類沖突,你可以將這2個類放在不同的包里面。OC中并沒有”包”的概念,也就是沒有命名空間機制,取而代之的是開發人員給類名加上前綴,使用前綴可以有效的防止類名沖突。比如NSString(OC中的字符串類)、NSArray(OC的數組類),它們的前綴都是NS 2.關鍵字都以@開頭 OC代碼中是可以混入C語言、C++代碼的,而C語言和C++作為一門編程語言,都有自己的關鍵字。為了防止跟C語言、C++關鍵字沖突,OC的關鍵字都以*@*開頭。 甚至字符串都是以@開頭的,比如@“Hello”是OC中的字符串,而”Hello”則是C語言中的字符串。 語法要點:

blob27.png Oc沒有垃圾回收; 源文件后綴為.m;入口程序同c,也是main() 導包使用 #import 也不用使用條件編譯加入頭文件;#import會自動判斷是否已經添加過該頭文件。

++ 面向對象語法+ 類 * 一般用2個文件來描述一個類; 1> .h:類的聲明文件,用于聲明成員變量、方法。類的聲明使用關鍵字@interface和@end。 [注意:.h中的方法只是做一個聲明,并不對方法進行實現。也就是說,只是說明一下方法名、方法的返回值類型、方法接收的參數類型而已,并不會編寫方法內部的代碼。] .m:類的實現文件,用于實現.h中聲明的方法。類的實現使用關鍵字@implementation和@end。 .h

//用于聲明Student這個類由哪些成員變量和方法(面對對象稱方法,面向過程稱函數)//導包,Foundation包含了常用的類,(類似java中的java.lang類)#import <Foundation/Foundation.h>//@interface表示聲明一個類,后是類名;必須要指定繼承的父類(java中是自動繼承object)// : 即是繼承//@end表示一個類的結束@interface Student : NSObject{ //成員變量要定義在大括號中; int age; int no;}//OC在.h中聲明的方法都是公用方法//Oc中凡是方法類型都用括號括起來(int)//成員變量age的get方法// - 代表動態方法,就是對象內部方法;+ 代表靜態方法- (int)getAge;//OC中不建議使用get*寫法,建議直接與變量名一樣-(int)age;//age的set方法;一個冒號對應一個參數- (void)setAge:(int)newAge;//同時設置兩個參數的set方法-(void)setAge:(int)newAge andNo:(int)newNo;-(int)no;@end

使用:

int main(int argc, const char * argv[]) { @autoreleasepool { //創建對象 //1.調用一個靜態方法alloc來分配內存 //2.創建一個該對象的指針指向剛創建的內存空間 Student *stu = [Student alloc]; //3.調用一個動態方法進行初始化; //相當于調用了Student對象的init方法; stu = [stu init]; [stu setAge:100]; [stu getAge]; [stu age]; //上面三步可合并為 Student *stu1 = [[Student alloc] init]; [stu1 setAge:10 andNo:101]; NSLog(@"age :%d,no %d:",[stu1 age],[stu1 no]); //釋放對象,但若選擇了ARC編譯器會自動添加 [stu release]; } return 0;}

++ 點語法 ++ 為了方便其他程序員熟悉而做的處理;其本質還是方法調用

Person *person = [[Person alloc] init]; //點語法,為了方便其他程序員熟悉而做的處理 // [person setAge:10]; // 注意:不是訪問成員變量;為了防止混淆,OC規范成員變量以_開頭 person.age = 10;//等效于[person setAge:10];( // int age = [person age]; int age = person.age;//等效于 int age = [person age];

方法名:

//方法也是方法名的一部分;故該方法的方法名是setAge:-(void)setAge:(int)newAge;//故該方法的方法名是setAge:andNo://-(void)setAge:(int)newAge andNo:(int)newNo;//方法名是age;-(int)age;

注意:

@implementation Person-(void)setAge:(int)newAge{ _age = newAge; //方法相當于[self setAge:newAge],即又調用了自身,則會無限循環調用自己// self.age = newAge;}-(int)age{ //相當于[self age],也會調用自身,會無限調用自己// return self.age; return _age;}@end

stu->age;是直接訪問成員變量,但只能訪問@public修飾的變量;

stu.age=18;是調用setAge方法。 ++ 構造方法 ++ .h中

//自定義一個構造方法,是一個動態方法,內部方法//由于系統的構造方法返回都是id,為保持一致,也返回id;(id可代表所有OC對象指針)-(id)initWithSize:(int)size andPRice:(double)price;

.m中

//實現構造方法-(id)initWithSize:(int)size andPrice:(double)price{ //首先要調用父類的實現方法 // self= [super init]; //再進行賦值 //父類返回的對象可能會為空 //相當于if (self!=nil) // if (self){ // _size = size; //或 self._size = size; // _price = price; // } //或者上面的可簡化為 if (self = [super init]) { _size = size; _price = price; } return self;}//重寫,類似于java中對象的toString//...同java,代表多個參數//NSString *str = @"str";是OC中的字符串,為區別C,都加 @;- (NSString *)description{ return [NSString stringWithFormat:@"size:%i,price:%f", _size,_price];}

//%@表示打印一個OC對象,需重寫(NSString *)description方法(同java的toString); NSLog(@” to string %@“,car);

…同java,代表多個參數 [所有返回*的地方都可以用id代替,且id是關鍵字,不能直接做變量名]

++ 變量的使用域: 類的成員變量默認是protected的,一般使用默認的即可,不需要添加修飾符 @public :全局都可訪問,成員變量可用->直接訪問; @protected:只能在類內部和子類訪問 @private :只能在類內部訪問 (OC中沒有包的的概念,故沒有default) - 代表動態方法,就是對象內部方法; + 代表靜態方法 [靜態方法同java,也可使用self,但不同的是在靜態方法中的self意思是指向的類名,而不是self對象] (即 誰調用方法,self就指向誰) 靜態方法不能訪問成員變量; 在頭文件中聲明的方法都是public的; 若直接寫在.m文件中的方法,沒有在.h文件中進行聲明,那么這個方法是私有方法

++ 內存釋放 系統自帶的靜態方法創建的對象都會自動釋放; 1.在定義時自動釋放: Car *car = [[[Car alloc] initWithSize:10 andPrice:23.0f] autorelease]; 2.手動釋放 [person release]; ** autorelease 是在適當的時機釋放,而不是馬上釋放. ++new ++ Student *stu= [Student new];//相當于Student *stu = [[Student alloc] init] 但很少用new,這是新版本才添加的關鍵字;

++ @property++ 生成set/get的聲明 為了解決set/get方法的冗余的麻煩; 只用在.h文件里,用于聲明方法(set/get) @property int age;//編譯器遇到@property時,會生動生成set/get方法的聲明

++ @synthesize++ 生成set/get的實現[同@property是編譯器的特性] 為了解決set/get的實現 @synthesize age,_no,height;//相當于三個成員變量的實現 [若用synthesize了,即可在.h文件中不寫成員變量age,_no,height,會默認去訪問與age同名的變量,若找不到同名的變量,會自動生成一個同名變量,并且若自己定義的成員變量的名字與@synthesize不一樣時,會默認創建自動生成的] [但為了統一風格,成員變量以_開頭,需要指定@synthesize默認生成的變量名,如:@synthesize age=_age,no=_no,height=_height;]

**故在定義類的成員變量時,一般需聲明變量名;直接在頭文件使用@property,.m文件中使用@synthesize; [Xcode在4.5后添加了新特性:.m文件中的@synthesize都可省略(會自動生成@synthesize age=_age,no=_no,height=_height;這句代碼,默認自帶下劃線),也就是直接在.h文件中用@property聲明即可] [但自己寫的set/get會優先使用;若自己手動實現了get/set方法,Xcode就不會自成生成@synthesize,也不會生成set/get方法]

++ 內存管理 ++ 管理范圍:任何繼承了NSObject的對象,對基本的數據類型不需要; 原理:每個對象內部都保存了一個與之有關的整數,稱為引用計數器;每當使用alloc,new,copy創建一個對象時,對象的引用計數器被設置為1;給對象發送一條retain消息,可以引用計數器值+1;給對象發送一條release消息,可使引用計數器值-1;當一個對象的引用計數器值為0時,那么它將被銷毀,其占用的內存被系統回收,OC也會自動向對象發送一條dealloc消息.一般會重寫dealloc方法,在這里釋放相關資源.[但一定不要直接調用dealloc方法,是系統自動調用該方法] — 可用retainCount消息獲得當前對象的引用計數器值; [java中new了一個對象后若沒有變量引用,則會自己銷毀;但在OC中,若新建了一個對象,沒有變量引用,計數器值會為1,若沒有手動回收或關閉app,則永不會被回收,]

- (void)dealloc{ NSLog(@"系統調用回收方法"); //一定要調用super的dealloc方法,而且最好放在最后面調用 [super dealloc];}

[stu release];方法只能調用一次,若調用多次,會發生野指針錯誤(訪問了不屬于你的內存)

— “誰創建,誰釋放”;若用alloc,new,copy的創建的對象,就必須調用release或autorelease來釋放;不是你創建的,就不用你去釋放; —“誰retain,誰release”只要調用retain,無論這個對象是誰創建的,都需要release釋放;

ARC特性(auto reference count):4.5后的新特性,由編譯器自動進行內存釋放;

++ 對象之間的內存管理 ++ //直接調用set的一個對象,對象沒有被回收,會造成內存泄露 [stu setBook:[[Book alloc] initWithID:100]]; 對象的set方法也會創建一個對象,對象的計數+1;需要對原對象釋放;

-(void)setBook:(Book *)book{if(_book != book){//傳進來的變量可能已經釋放,為了正確,需判斷是否為同一個,不是同一個才進行釋放和引用;也能保證在多次調用時引用的計數器值不會增加,不會出現內存泄露的情況; [_book relase];//先釋放舊的成員變量,且不用擔心空指針; _book = [book retain];//再retain傳進來的對象}}[//可在頭文件中用 @property (retain )Book *book;代替上面的set方法 ]

[**OC中若對象為nil,調用其方法不能出現空指針異常] [stu release];/若stu已經釋放過了再釋放,是野指針會出錯 [nil release];//是空指針,再釋放,不會報錯; //野指針;在內存中指針仍保留原地址,但現在該塊內存的內容已不在原來的內容,也不于屬于原內容,故會報錯;為避免報錯,需要清空原指針(相當于java中的置null) stu = nil;//清空指針中的地址; ++ 若類中有成員變量是自定義的對象,要先釋放:

- (void)dealloc{ NSLog(@"系統調用回收方法"); //一定要調用super的dealloc方法,而且最好放在最后面調用 //成員變量要釋放 [_book release];// NSLog(@"內部對象book計數值:%i",[_book retasinCount]); [super dealloc];}

++ 通常引用一個類的兩種方法:#import;@class; ++ @class ++用于聲明一個類,不知道實現,在使用時才用#import **若在.h文件中只是要用到某個類,如定義一個成員變量,沒必要用#import “Book.h”;這樣是把.h文件的內容拷貝到此處,影響性能(若有上百個類用#import一個類A,A中使用一點改動,則所有子類都會重新編譯;而@class則不會); 若只是聲明一個成員變量,只用使用@class Book;即可,聲明Book這個類即可,提高效率; [對自定義的對象相互持有的情況下必須用 @class;如A中有B,B中有A;就不能使用#import,會造成遞歸導入;編譯錯誤] [對于繼承的父類,不能使用@class,須使用#import,用于將父類的頭文件拷貝到此處,讓子類知道哪些方法已經定義過。] 但在.m要用到這個類下的方法,還是需要#import “Book.h”

++ @property 內存管理 ++ @(參數1,參數2)類型 名字; 參數分類: 讀寫屬性:readwrite/readonly;//默認是readwrite,并生成set/get;readonly代表只生成get方法 setter屬性:assign/retain/copy;//默認是assign,直接賦值;retain,引用+1; 原子性:atomic/nonatomic;//默認atomic,加鎖,提供了多線程安全;nonatomic,禁止多線程,變量保護,可提高性能;[對于在iPone這個小型設備上,內存很小,默認情況下不需要考慮太多的多線程,以提高性能] (在做IOS開發時,盡量多使用nonatomic) 如:

@property (nonatomic,assign) int ID;@property (nonatomic,retain) Book *book;@property (nonatomic,getter=isEnable) BOOL enable;//指定get的方法名;@property (retain)Card *card;//就相當于上面手動判斷,釋放再retain的set方法;(若是基礎類型不需要添加,否則要添加retain)

++autorelease pool ++自動釋放池 OC中的一種內存自己回收機制,一般可將一些臨時變量添加到自動釋放池中,統一回收釋放; 當自動釋放池銷毀時,池里面的所有對象都會調用一次release方法; 使用:OC對象只需要發送一條autorelease消息,就會把這個對象添加到最近的自動釋放池中(棧頂的釋放池);autorelese實際上是把對release的調用延遲了,對于每一次autorelease,系統只是把該對象放入了autorelease pool中,當pool被釋放時,該pool會調用一次所有的對象relase方法。 [若使用autorelease 后就不需手動釋放] [autorelease pool會在程序執行完成后銷毀]

//代表創建一個自動釋放池; @autoreleasepool { // testMemoeryReales(); Student *stu = [[Student alloc] init]; //只是把對象放到autorelease pool中;當autoreleasepool被銷毀時,會自動調用一次池里所有的對象的release方法, [stu autorelease]; //則上面可簡化成 Student *stu1= [[[Student alloc] init] autorelease]; }

*[IOS5.0之前: NSAutoreleasePool *pool = [[NSAutorelease] alloc]init]; [pool release];(在ARC下,不能使用這種方法,只能使用@autoreleasepool;ARC本質上就是一個釋放池的操作)]

[NOTE:*不要在一個autoreleasepool中放入大量循環操作(for,while等,應使用手動release);盡量以免對大內存使用方法,對于這種延遲釋放機制,盡少使用;SDK中一般利用靜態方法創建并返回的對象都是已經autorelease的,不需要再release操作;] 自定義一個快速創建的構造方法: +(id)student{ return [[[Student alloc] init] autorelease]; } [規范:靜態方法返回的對象都是自己負責釋放的]

感謝李明杰老師@M了個J的講解及時詳細的課件(http://www.cnblogs.com/mjios)

博客地址:IOS學習筆記之Object-C(一)


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 安平县| 澄迈县| 昆明市| 军事| 松阳县| 富源县| 民勤县| 芒康县| 凌云县| 博乐市| 甘孜| 玛纳斯县| 海丰县| 敦化市| 恭城| 湖南省| 富川| 北安市| 昂仁县| 山阴县| 邵阳市| 民乐县| 长海县| 宿州市| 望城县| 麻城市| 咸丰县| 永城市| 江都市| 浦东新区| 遂川县| 浦城县| 丹阳市| 尚志市| 普洱| 城口县| 山西省| 古蔺县| 秀山| 红桥区| 南安市|