1、語法基礎objective-c
1.OC的語法數組
關鍵字基本上都是以@開頭,特例:self super id 等等;多線程
字符串以@開始;框架
BOOL: YES、NO;空:nil;函數
NSLog(@"Hello");性能
2.包含框架的主頭文件就能夠包含全部的.H,及.*的做用。ui
3.方法與對象:this
對象的方法都是以減號-開始;atom
對象方法的聲明必須在@interface和@end之間;url
對象方法的實現必須在@implementation和@end之間;
函數能夠寫在任意位置;
4.方法的參數
OC方法中,一個參數對應一個冒號;
冒號前須要加個說明;
冒號也是方法名的一部分;
- (int)pingFang:(int)num;
-(int)sumWithNum1:(int)num1 andNum2:(int)num2;
int n =[object pingFang:10];
int m = [object sumWithNum1:10 andNum2:5];
5.self
self 表明當前調用的對象或者類;this只能用在對象方法中;
6.多態
父類指針指向子類對象;
父類類型的變量,不能用來調用子類的方法;
7.字符串NSString
NSString *str = @"itcast"; NSLog(@"我在%@上課",str); int age =15; int no= 5; NSString *name = @"Andy"; NSString *newStr = [NSString stringWithFormat:@"My age is %d and no is %d",age,no]; int size = [name length];
8.註釋:
#pragma mark 註釋標籤
9.點語法
點語法的本質是方法調用;
stu.age=10;
編譯器:[stu setAge:10];
int nAge=stu.age;
編譯器:int nAge = [stu age];
10.set get的編譯化
XCode 4.4之後 @property 獨攬了@synthesize的功能
#import<Foundation/Foundtation.h> @interface Person:NSObject { int _age; NSString *_name; } @property int age; @property NSString* name; @end; @implementation Person @synthesize age=_age; @synthesize name = _name; @end
11. id類型
id 至關於 NSObject*
id 是萬能指針;能指向和操做任何OC對象;
id d = [Person new];
12.構造方法
完成的建立一個可用的對象須要兩部:
1.分配存儲空間 +alloc;
2.初始化 -init
Person *p=[Person new]; //1.分配存儲空間 Person *p1 = [Person alloc]; //2.使用-init進行初始化 Person *p2 = [p1 init]; Person *p3 =[[Person alloc] init]; //重寫Person的init方法 -(id) init { //必定要調用super的init方法:初始化父類的其餘的成員變量和屬性 //self = [super init]; if(self = [super init]) { //初始化成功 _age = 10; } return self; }
3.自定義構造方法規範
a.必定是對象方法;
b.返回類型通常是id類型;
c.方法名通常以init開頭
13.Category 分類
不改變原來類的基礎上,添加類的方法;
//聲明
@interface 類名(分類名稱)
@end
//實現
@implementation 類名(分類名稱)
分類只能增長方法,不能增長成員變量;
分類方法實現中能夠訪問原來類的中成員變量;
分類方法的實現優先級最高,而後是原來類,而後是父類,這樣會致使原來的方法失效;
14.類的加載和初始化
a.當程序啓動時,就會加載項目中全部的類和分類,並且加載後會調用每一個類和分類的+load
方法;
b.當第一次使用某個類時,就會調用當前類的+initialize方法;
c.先加載父類,再加載子類;
d.先初始化子類,再初始化子類;
15.description方法
默認狀況下,NSLog和%@輸出對象時,結果是:<類名:內存地址>
1.會調用對象的p的-description方法;
2.拿到-description方法的返回值(NSString *)顯示到屏幕上
16. SEL
-(void) test;
-(void) test2:(NSString *)str;
[p test];
1.把方法包裝成SEL類型的數據;
2.根據SEL數據找到test方法;
3.根據方法地址調用對應的方法;
[p performSelector:@selector(test)];
[p performSelector:@selector(test2:) withObject:@"123"];
2、內存管理
1.引用計數器
給對象發送retain消息,可使引用計數器+1;
給對象發送release消息,可使引用計數器-1;
能夠給對象發送retainCount消息得到當前的引用計數器值;
2.對象的銷燬
一個對象的引用計數器爲0時;那麼它將被銷燬;
當一個對象被銷燬時,系統會自動向對象發送一條dealloc方法;
Person類的實現 -(void) dealloc { NSLog("對象被銷燬"); [super dealloc]; } //alloc 和release要成對出現; //retain和release需成對出現;
3.OC不存在空指針錯誤,給空指針發送消息不報錯;
4.retain方法會返回對象自己;
5.set方法的內存管理
基本數據類型,直接複製;
- (void) setCar:(Car*) car { if(car != _car) { [_car release]; _car = [car retain]; } } - (void)dealloc { [_car release]; }
6.@property參數
1.set方法內存管理相關參數
a.@property (retain) Book *book; retain:release舊值,retain新值;
b.assign:直接賦值,適用於非OC對象類型;
c.copy:release舊值,copy新值;
2.是否生成set方法
readwrite:同時生成setter,getter的聲明、實現;(默認)
readonly:只會生成getter的聲明、實現;
3.多線程管理
nonatomic:不加鎖;性能高,必定要加。
atomic:加鎖,默認
4.setter和getter方法的名稱
@property (getter=methodName,setter=setName:)int height;
setter方法必定要有冒號:,不經常使用;
通常經常使用於BOOL 類型的getter方法名的修改
@property (getter=isRich) BOOL rich;
7.循環retain和@class
循環retain的解決方案:
一端用retain,一端用assign;
@property(nonatomic,retain) Card *card;
@property(nonatomic,assign) Person* person;
8.autorelease
//autorelease方法會返回對象自己 //autorelease會將對象放到一個自動釋放池; //當自動釋放池被銷燬時,會對池子的全部對象作一次release操做; //建立對象時,不要直接用類名;通常用self代替。 int main() { @autoreleasepool {//開始表明建立了釋放池 Person *p = [[[Person alloc] init] autorelease]; return 0; }//結束表明銷燬釋放池 } + (id)person { //使用Person會出現子類調用時,返回的指針類型仍是父類的問題 //return [[[Person alloc] init] autorelease] ; return [[[self alloc] init] autorelease] ; } +(id)personWithAge:(int) age { //Person*p = [[[Person alloc] init] autorelease] ; Person*p =[self person]; p.age =age; return p; }
9.ARC機制
//ARC ARC的判斷準則: 只要沒有強指針指向對象,就會釋放對象; 指針分2種: 1.強指針:默認狀況下,全部指針都是強指針 __strong 2.弱指針:__weak //strong 等價於以前的 retain // @property (nonatomic,strong) Dog *dog; @property (nonatomic,weak) Dog *dog; ARC的特色: 1.不容許調用release、retain、retainCount; 2.容許重寫dealloc,可是不容許調用[super dealloc] 3.@property的參數 *strong:成員變量是強指針(適用於OC對象類型); *weak:成員變量是弱指針; * assign:適用於非OC對象類型; 4.之前的retain,修改成strong,其餘一切不變。 5.若是兩端互相引用,一端用strong,一端用weak;
3、其餘數據類型
1.Block
Block的做用是來封裝代碼,能夠在任什麼時候候執行;
#import <Foundation/Foundation.h> typedef int(*Sump) (int,int); typedef int(^MyBlock)(int,int); int main() { int(^sumBlock)(int,int); sumBlock = ^(int a,int b){ return a+b; }; MyBlock sum2Block = ^(int a,int b){ return a+b; }; return 0; } void test2() { int (^sumBlock)(int,int)= ^(int a,int b) { return a+b; }; int c = sumBlock(10,11); NSLog(@"%d",c); //用一個block輸入n條橫線 void (^lineBlock)(int)= ^(int n) { for (int i=0; i<n; i++) { NSLog(@"------------"); } }; lineBlock(5); } void test() { //block用來保存一段代碼 //block的標識:^ /* block跟函數很像: 1.能夠保存代碼 2.有返回值 3.有形參 block訪問外邊的變量: 1.默認狀況下,block能夠訪問外面的變量; 2。默認狀況下,block不能修改外面的變量 3.給局部變量加上__block關鍵字,這個局部變量能夠在內部修改; 利用typedef定義block類型 typedef int(^MyBlock)(int,int); 之後利用MyBlock來定義block變量 MyBlock sum2Block = ^(int a,int b){ return a+b; }; */ //定義block變量 //若是block沒有形參,後面的括號能夠省略 void (^myblock)()= ^{ NSLog(@"test-----------"); }; //利用block變量調用block內部的代碼 myblock(); }
2.@protocol 協議
#import <Foundation/Foundation.h> //定義了一個名叫MyProtocol的協議 @protocol MyProtocol <NSObject> //@required 要求實現,不實現就會發出警告;默認 //@optional 不要求實現。 //一個協議遵照了某一份協議,就能夠擁有另外一個協議中的全部聲明方法 //NSObject 是全部類的基類,也是基協議 //要求某個對象遵照這個協議 // NSObject<MyProtocol> *obj = 遵照該協議的類的對象; /* 1.協議的定義: @protocol 協議名稱 <NSObject> //方法聲明列表... @end 2.如何遵照協議: 1>類遵照協議: @interface 類名:父類名 <協議名稱1,協議名稱2> @end 2>協議遵照協議: @protocol 協議名稱 <其餘協議名稱1,其餘協議名稱2> @end 3.協議中方法聲明的關鍵字: 1>@required 要求實現,不實現就會發出警告;默認 2>@optional 不要求實現。 4.定義一個變量的時候,限制這個變量的對象遵照某個協議 類名<協議名稱> *變量名;或者 id<協議名稱> 變量名; 5.@property中聲明的屬性也可用作一個遵照協議的限制 @property(nonatomic,strong) 類名<協議名稱> *屬性名; @property(nonatomic,strong) id<協議名稱> 屬性名; 6.協議可定義在其餘單獨文件中, 也能夠定義在某個類中 1>若是這個協議只用在某個類中,則定義在該類中; 2>若是用在多個多個類中,則定義在單獨文件種。 */ @required - (void)test; @optional - (void)test2; @end
4、Foundation框架
一、結構體
int main() { /* NSRange(location,length) NSPoint\CGPoint NSSize\CGSize NSRect\CGRect */ CGPoint point = NSMakePoint(10, 10); CGPoint point2 = CGPointMake(10, 10);//經常使用 CGSize size = NSMakeSize(10, 10); CGSize size2 = CGSizeMake(10, 10); CGRect rect1 = CGRectMake(10, 10, 50, 50); CGRect rect2 = {{0,0},{50,50}}; CGRect rect3 = {point,size}; CGRect rect4 = {CGPointZero,CGSizeMake(100, 90)}; NSString *str = NSStringFromPoint(point); //比較兩個點是否相同 BOOL bIsSame =CGPointEqualToPoint(point, point2); BOOL bIsContain = CGRectContainsPoint(rect1, point); return 0; } void testRange() { //@「i love oc」; // NSRange r1={2,4};//不用 // NSRange r2={.location=2,.length=4};//不經常使用 // NSRange r3 = NSMakeRange(2, 4);//經常使用 NSString *str=@"i love oc"; //查找字符串在str中的範圍 //若是找不到,length=0;location=NSNotFound==-1 NSRange range=[str rangeOfString:@"love"]; NSLog(@"loc=%ld,length=%ld",range.location,range.length); }
二、字符串
/* 1.字符串建立 */ NSString *str1=@"hello"; NSString *str2=[[NSString alloc] initWithFormat:@"age is %d",10]; NSString *str3 = [[NSString alloc] initWithUTF8String:"abc"]; const char *cs = [str3 UTF8String]; //從文件中讀取 NSString *str4 = [[NSString alloc] initWithContentsOfFile:@"/Users/chenwei/Desktop/objective-c-01.m" encoding:NSUTF8StringEncoding error:nil]; // NSLog(@"%@",str4); //URL:資源路徑 //協議頭://路徑 //本地文件,協議頭 file:// NSURL *url = [[NSURL alloc] initWithString:@"file:///Users/chenwei/Desktop/objective-c-01.m"]; NSString *str5 = [[NSString alloc] initWithContentsOfURL: url encoding:NSUTF8StringEncoding error:nil]; NSLog(@"%@",str5); //經常使用方法.通常都用一個類方法與對象方法對應。 NSString *str6 = [NSString stringWithFormat:@"age is %d",10]; NSURL *str7 = [NSURL URLWithString:@""];
三、數組
/* NSArray: 不可變數組 NSMutableArray:可變數組 @[] 只建立不可變數組NSArray */ int main(int argc, const char * argv[]) { NSMutableArray *array=[NSMutableArray array]; [array addObject:@"Jack"]; [array addObject:@"Rose"]; //nil不能添加 //[array addObject:nil]; //刪除元素 //[array removeAllObjects]; return 0; } void useArray() { /* 1.NSArray 建立 */ //OC數組只能存放OC對象、不能放非OC對象,好比int、struct等 //NSArray *array = [NSArray array]; NSArray *array2 = [NSArray arrayWithObject:@"jack"]; //nil是數組元素結束的標記 NSArray *array3=[NSArray arrayWithObjects:@"jack", @"Rose",nil]; //快速建立數組的方式 NSArray *array4=@[@"jack",@"rose",@"others"]; /* 2.NSArray 個數 */ int nCount = array2.count; /* 3.NSArray 遍歷 */ for (int i=0; i<array4.count; i++) { NSLog(@"%@",array4[i]); } for(id obj in array4) { NSUInteger nIndex = [array4 indexOfObject:obj]; NSLog(@"%ld---%@",nIndex,obj); } //NSLog(@"%ld",array3.count); [array4 enumerateObjectsUsingBlock: //沒遍歷到一個元素,就會調用一次block //而且當前元素和索引位置當作參數傳遞給block ^(id obj, NSUInteger idx, BOOL *stop) { NSLog(@"%ld---%@",idx,obj); if (idx == 0) { //中止遍歷 *stop = YES; } }]; void (^myBlock)(id,NSUInteger,BOOL *) = ^(id obj, NSUInteger idx, BOOL *stop) { NSLog(@"%ld---%@",idx,obj); if (idx == 0) { //中止遍歷 *stop = YES; } }; for (int i=0; i<array4.count; i++) { BOOL bIsStop = NO; id obj = array4[i]; myBlock(obj, i, &bIsStop); if (bIsStop) { break; } } }
四、字典
int main(int argc, const char * argv[]) { /* 字典: key------>value 索引------>文字內容 裏面存儲的都是鍵值對 */ NSDictionary *dict4=@{@"name": @"jack",@"address":@"北京"}; NSArray *keys = [dict4 allKeys]; for (int i=0; i<dict4.count; i++) { NSString *key = keys[i]; NSString *object = dict4[key]; NSLog(@"%@------%@",key,object); } [dict4 enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { NSLog(@"%@------%@",key,obj); }]; return 0; } void useMutableDictionary() { NSMutableDictionary *dict = [NSMutableDictionary dictionary]; [dict setObject:@"Jack" forKey:@"name"]; [dict setObject:@"北京" forKey:@"address"]; [dict setObject:@"Rose" forKey:@"name"]; //[dict removeAllObjects]; NSLog(@"%@",dict); } void userDictionary() { NSDictionary *dict = [NSDictionary dictionaryWithObject:@"jack" forKey:@"name"]; id obj = [dict objectForKey:@"name"]; NSArray *keys=@[@"name",@"address"]; NSArray *objects=@[@"jack",@"北京"]; NSDictionary *dict2 = [NSDictionary dictionaryWithObjects:keys forKeys:objects]; NSDictionary *dict3 = [NSDictionary dictionaryWithObjectsAndKeys: @"jack",@"name", @"beijng",@"address", nil]; //經常使用方式 NSDictionary *dict4=@{@"name": @"jack",@"address":@"北京"}; id obj2 = [dict4 objectForKey:@"name"]; id obj3 = dict4[@"name"]; NSLog(@"%@",obj2); NSLog(@"%@",obj3); //返回鍵值對的個數 NSLog(@"%ld",dict4.count); }
五、NSNumber和NSValue
int main(int argc, const char * argv[]) { //NSNumber之因此能包裝基本數據類型爲對象,是由於集成了NSValue NSNumber *num = [NSNumber numberWithInt:10]; NSDictionary *dict= @{ @"name":@"jack", @"age":num, }; NSNumber *num2 = dict[@"age"]; int nNum = [num2 intValue]; NSLog(@"%d",nNum); //@20將20包裝成一個NSNumber對象 NSDictionary *dict2= @{ @"name":@"jack", @"age":@20, }; int age = 10; NSNumber *ageNum= @(age); //將結構體包裝成OC對象,使用NSValue。 CGPoint p = CGPointMake(10, 10); NSValue *pValue = [NSValue valueWithPoint:p]; NSArray *array =@[pValue]; //將value轉換成對應的結構體 NSPoint newPoint = [pValue pointValue]; return 0; }
六、日期
int main(int argc, const char * argv[]) { //建立一個時間對象 NSDate *date = [NSDate date]; NSLog(@"%@",date); //oc的時間都爲秒 NSDate *date2 = [NSDate dateWithTimeInterval:5 sinceDate:date]; //從1970年開始走過的秒數 NSTimeInterval secondsFrom1970 = [date2 timeIntervalSince1970]; //日期格式化類 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; // y 年 M 月 d 日 // m 分 s 秒 H(24小時) h(12小時) formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss"; NSString *str = [formatter stringFromDate:date]; NSLog(@"%@",str); //字符串,轉換成NSDate NSString *str2 = @"2011/09/10 18:56"; NSDateFormatter *formatter2 = [[NSDateFormatter alloc] init]; formatter2.dateFormat = @"yyyy/MM/dd HH:mm"; NSDate *date3 = [formatter2 dateFromString:str2]; return 0; }
七、Copy
@interface Person : NSObject <NSCopying> //copy表明set方法會release舊對象、copy新對象 //修改外面的變量,並不會影響到內部的成員變量 //建議:NSString通常用copy策略,其餘對象通常用retain @property (nonatomic,copy) NSString *name; + (id) personWithName:(NSString *)name; @end #import "Person.h" @implementation Person + (id) personWithName:(NSString *)name { Person *person = [[[self class] alloc] init]; person.name = name; return person; } - (id)copyWithZone:(NSZone *)zone { //這裏建立的copy對象不要求釋放 Person *copy = [[[self class] allocWithZone:zone] init]; copy.name = self.name; return copy; } @end
8.反射
NSString *str = @"Person"; Class class = NSClassFromString(str); Person *person = [[Class alloc] init]; NSLog(@"%@",person); NSString *name = NSStringFromClass([Person class]); //方法反射 NSString *method = @"test"; SEL selector = NSSelectorFromString(method); [person performSelector:selector];