Objective-C學習筆記

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];
相關文章
相關標籤/搜索