學習ios【1】Objective-C 基本語法


一 了解一下,找參考資料

1.看書學習object-c語法,第一本看的是《objective-c程序設計》。

2.官網:https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html

二 定義類

1. 格式

object-c中定義類的方式和c#不同,它分為兩個部分,一般放在兩個獨立的文件中:

①在@interface部分聲明類,文件格式.h;

②在@implementation部分實現類,文件格式.m。

2.@interface 部分

Fraction.h

#import <Foundation/Foundation.h>

@interface Fraction : NSObject
-(void)setAge:(int)age;
-(int)getAge;

@end

以上代碼有幾點說明:

①NSObject是默認的父類;

②方法前面的負號(-)表示這是一個實例方法;如果是正號(+)表示這是一個類方法。

3. @implementation 部分

Fraction.m

#import "Fraction.h"

@implementation Fraction
{
int _age;
}
-(void)setAge:(int)age
{
_age=age;
}
-(int)getAge
{
return _age;
}

@end

4.調用

注意:@autoreleasepool引入了自動計數處理內存釋放問題;看一下對象初始化和方法調用的格式。

main.m

#import <Foundation/Foundation.h>

#import "Fraction.h"

int main(int argc, const char * argv[])
{
@autoreleasepool {

//對象初始化
Fraction *fraction=[Fraction alloc];
        fraction=[fraction init];

//調用方法
        [fraction setAge:100];
int age=[fraction getAge];

//打印結果
NSLog(@"the age is %i",age);
    }

}

三 基本數據類型

1. 基本類型

object-c的幾種基本數據類型: int ,float,double,char

image

2.float類型

NSLog轉換字符為 %f或者%g

NSLog(@"The float result is %f",f);//The float result is 1.230000

NSLog(@"The float result is %g",f);//The float result is 1.23

3.字符串

用@開頭並且放在雙引號中的字符串是NSString字符串類型。

各類型的NSLog輸出轉換如下:
int main(int argc,const char* argv[]){
    @autoreleasepool{
        int a=100;
        NSLog(@"the integer value is %i",a);
        float f=1.23;
        NSLog(@"The float result is %f",f);//The float result is 1.230000
        NSLog(@"The float result is %g",f);//The float result is 1.23
        double d=1.2345;
        NSLog(@"The double value is %e",d);//The double value is 1.234500e+000
        char c='V';
        NSLog(@"The char value is %c",c);//The char value is V
    }
    return 0;

}

4.id類型

id數據類型可以存儲任何類型的對象。id類型是多態和動態綁定的基礎。

5.布爾類型

objective-c中的布爾值是YES和NO.

int main(int argv,const char * argc[])
{
@autoreleasepool {
for(int i=2;i<=50;i++)
        {
bool isPrime=YES;
for(int j=2;j<i;j++)
            {
if(i%j==0)
                {
                    isPrime=NO;
continue;
                }
            }
if(isPrime==YES)
            {
NSLog(@"%i",i);
            }
        }
    }
return 0;

}

四 scanf和NSLog

scanf  :接收輸入值,第一個參數始終是C風格的字符串,第二個參數用於指定用戶輸入的值儲存在哪里;

NSLog:輸出結果,第一個參數始終是NSString。

int main(int argc, const char * argv[])
{
@autoreleasepool {
int number;
NSLog(@"請輸入要計算的數值?");
scanf("%i",&number);
int result=0;
for(int i=1;i<=number;i++)
        {
            result+=i;
        }

NSLog(@"The Triangular number of %i is %i",number,result);

    }
return 0;

}

五 類

1 合成存取方法

所謂合成存取方法,就是自動設值和取值,類似於c#中的屬性。它的定義和使用步驟為:

①在 @interface 中使用 @property 標識屬性;

②在 @implementation 中使用 @synthesize 指令;

③調用屬性方法,可以使用傳統的方括號語法,也可以使用點運算符進行屬性讀寫。

Fraction.h

#import <Foundation/Foundation.h>
@interface Fraction : NSObject

@property int number1,number2;

-(void)print;

@end

Fraction.m

#import "Fraction.h"
@implementation Fraction

@synthesize number1,number2;
-(void)print
{
NSLog(@"number1 is %i,number2 is %i",number1,number2);

}

@end

main.m

#import <Foundation/Foundation.h>
#import "Fraction.h"

int main(int argc, const char * argv[])

{

@autoreleasepool {

Fraction *fraction=[Fraction alloc];
        fraction=[fraction init];

//調用方式1
        [fraction setNumber1:10];
        [fraction
setNumber2:20
];
        [fraction print];
//調用方式2
        fraction.number1=30;
        fraction.
number2=40;

        [fraction print];

    }

}

2.多個參數的方法

例如我們想同時設置上述例子Fraction中的number1和number2的值,可以使用帶多個參數的方法。(說實話,第一次看到這個語法的時候尷尬症都犯了。)

Fraction.h

#import <Foundation/Foundation.h>
@interface Fraction : NSObject
@property int number1,number2;
-(void)print;
-(void)setNumber1:(int)n1 andNumber2:(int)n2;

@end

Fraction.m

#import "Fraction.h"
@implementation Fraction
@synthesize number1,number2;
-(void)print
{
NSLog(@"number1 is %i,number2 is %i",number1,number2);
}
-(void)setNumber1:(int)n1 andNumber2:(int)n2
{
number1=n1;
number2=n2;
}

@end

main.m

#import <Foundation/Foundation.h>

#import "Fraction.h"

int main(int argc, const char * argv[])

{

@autoreleasepool {

Fraction *fraction=[Fraction alloc];
        fraction=[fraction init];

        [fraction setNumber1:50 andNumber2:60];
        [fraction print];
    }

}

3.方法帶引用類型的參數

Fraction.h

#import <Foundation/Foundation.h>
@interface Fraction : NSObject
        @property int number1,number2;
        -(void)print;
        -(void)setNumber1:(int)n1 andNumber2:(int)n2;
        -(void)add:(Fraction*)f;

@end

Fraction.m

#import "Fraction.h"
@implementation Fraction
@synthesize number1,number2;
-(void)print
{
        NSLog(@"number1 is %i,number2 is %i",number1,number2);
}
-(void)setNumber1:(int)n1 andNumber2:(int)n2
{
        number1=n1;
        number2=n2;
}
-(void)add:(Fraction *)f
{
        number1+=f.number1;
        number2+=f.number2;
}

@end

main.m

#import <Foundation/Foundation.h>

#import "Fraction.h"

int main(int argc, const char * argv[])
{

        @autoreleasepool {

        Fraction *f1=[[Fraction alloc] init];
        Fraction *f2=[[Fraction alloc] init];
        [f1 setNumber1:1 andNumber2:2];
        [f2 setNumber1:3 andNumber2:4];
        [f1 add:f2];
        [f1 print];
    }

}

六 繼承

1. 繼承

我們所定義的類都是從NSObject繼承而來。

繼承實例: 在這個例子中Rectangle是父類,Square是子類。

XYPoint.h

#import <Foundation/Foundation.h>

@interface XYPoint : NSObject
        @property int x,y;
        -(void)setX:(int)x andSetY:(int)y;

@end

XYPorint.m

#import "XYPoint.h"

@implementation XYPoint
@synthesize x,y;
-(void)setX:(int)xVal andSetY:(int)yVal
{
在這個例子中Rectangle是父類,Square是子類        x=xVal;
        y=yVal;
}

@end

父類:

Rectangle.h

#import <Foundation/Foundation.h>

#import "XYPoint.h"

@interface Rectangle : NSObject
@property int width,height;
       -(void)setWidth:(int)w andSetHeight:(int)h;

       -(int)area;

       -(void)setOrignal:(XYPoint *)original;

       -(XYPoint *)original;

@end

Rectangle.m

#import "Rectangle.h"

@implementation Rectangle

{
       XYPoint * _original;

}

@synthesize width,height;
-(void)setWidth:(int)w andSetHeight:(int)h
{
       width=w;
       height=h;
}
-(int)area
{
       return width*height;

}

-(int)area
{
       return width*height;
}
-(void)setOrignal:(XYPoint *)p
{
       _original=p;
}
-(XYPoint *)original
{
       return _original;

}

@end

子類

Square.h

#import <Foundation/Foundation.h>
#import "Rectangle.h"
@interface Square : Rectangle
-(void)setSide:(int)s;
-(int)side;

@end

Square.m

#import "Square.h"

@implementation Square
-(void)setSide:(int)s
{
    [self setWidth:s andSetHeight:s];
}
-(int)side
{
       return self.width;
}

@end

main.m

#import "Rectangle.h"
#import "Square.h"
int main(int argc,const char * argv[])
{
@autoreleasepool {

       //父類
       Rectangle *rectangle=[[Rectangle alloc] init];
        [rectangle setWidth:5 andSetHeight:6];
       NSLog(@"rectangle w=%i,h=%i,area=%i",rectangle.width,rectangle.height,[rectangle area]);

       //子類
       Square *square=[[Square alloc] init];
        [square setSide:8];
       NSLog(@"square side=%i,area=%i",square.side,[square area]);

    }

return 0;

}

 

2.覆蓋

如果子類使用和父類相同的名稱定義的方法,可以覆寫父類中的方法。新方法必須具有相同的返回類型,並且參數的數目與覆寫方法完全一致。例如下面的例子中ClassB覆寫了ClassA的initVar方法。

ClassA.h

#import <Foundation/Foundation.h>

@interface ClassA : NSObject
       {
              int x;
       }
       -(void)initVar;
       -(void)print;

@end

ClassA.m

#import "ClassA.h"

@implementation ClassA
-(void)initVar
{
       x=1;
}
-(void)print
{
       NSLog(@"x=%i",x);
}

@end

ClassB.h

#import <Foundation/Foundation.h>
#import "ClassA.h"
@interface ClassB : ClassA
       -(void)initVar;

@end

ClassB.m

@implementation ClassB
-(void)initVar
{
       x=2;
}

@end

main.m

#import "ClassB.h"
int main(int argc,const char * argv[])
{
@autoreleasepool {
ClassB * b=[[ClassB alloc] init];

        [b initVar];

        [b print];// x=2

    }
return 0;

}

七 id類型和動態綁定

1. id可以用來存儲屬於任何類的對象。

例如:

#import "Complex"

int main(int argc,const char * argv[])
{
@autoreleasepool {

       id d1=[[Complex alloc] init]; //Complex *c1=[[Complex alloc] init];

        [d1 setReal:1 andImaginary:2];
       id d2=[[Comlex alloc] init];
        [d2 setReal:3 andImaginary:4];
        [d1 print];
       NSLog(@"     +");
        [d2 print];
       NSLog(@"-------");
       id d3=[d1 add:d2];
        [d3 print];
    }
return 0;

}

注意,這里id類型的聲明中不使用星號。

為了盡量在編譯期間就識別到更多地錯誤,並且增強程序的可讀性,不要養成濫用id這種通用數據類型的習慣。盡量使用靜態類型和有意義的變量名來提高程序的可讀性。

八 捕捉異常

@try …@catch可以捕獲到程序中的異常,如下所示:

int main(int argc,const char * argv[])
{
@autoreleasepool {

@try {

           ... 

        }
@catch (NSException *ex) {
NSLog(@"error name:%@ ;reason:%@",[ex name],[ex reason]);
        }
@finally {
NSLog(@"done");
        }
return 0;
    }

}

當出現異常時,會執行@catch代碼塊,參數NSException對象包含了異常的詳細信息,name方法返回異常的名稱,reason方法給出異常的詳細信息。

九 變量和數據類型

1.自定義對象的初始化方法

在前面的例子中,我們創建對象並且初始化都是這樣做的:

Complex *c1=[[Complex alloc] init];

[c1 setReal:10 andImaginary:20];

接下來我們自定義對象的初始化方法,一般也是以init開頭。

Complex.h

@interface Complex : NSObject
@property double real,imaginary;
-(void)print;

-(void)setReal:(double)r andImaginary:(double) m;

-(Complex *)initWithReal:(double)r andImaginary:(double) m;

@end

Complex.m

#import "Complex.h"

@implementation Complex
@synthesize real,imaginary;
-(void)print
{
NSLog(@"%g + %gi",real,imaginary);
}
-(void)setReal:(double)r andImaginary:(double)m
{
real=r;
imaginary=m;

}

-(Complex *)initWithReal:(double)r andImaginary:(double)m
{
self=[super init];
if(self)
    {
        [
self setReal:r andImaginary:m];
    }
return self;
}

@end

main.m

#import "Complex.h"
int main(int argc,const char * argv[])
{

@autoreleasepool {

        Complex *c=[[Complex alloc] initWithReal:10 andImaginary:20];
        [c print];

    }

return 0;

}

2.靜態變量

靜態變量定義在所有方法之外,使用static修飾符,它屬於類,而不屬於類對象。例如在下面的例子中,使用gCount變量記錄allocC調用次數。

Complex.h

#import <Foundation/Foundation.h>

@interface Complex : NSObject

@property double real,imaginary;

...

+(Complex *)allocC;
+(int)count;

@end

Complex.m

#import "Complex.h"
static int gCount=0;
@implementation Complex

...

+(Complex *)allocC
{
gCount++;
return [Complex alloc];
}
+(int)count
{
return gCount;
}

@end

main.m

#import "Complex.h"
int main(int argc,const char * arg[])
{
@autoreleasepool {
NSLog(@"count=%i",[Complex count]);//0
Complex *c=[[Complex allocC] init];
Complex *c1=[[Complex allocC] init];
Complex *c2=[[Complex allocC] init];
NSLog(@"count=%i",[Complex count]);//3
    }
return 0;

}

十 分類和協議

1.分類

通過分類可以很簡單地向現有類添加方法,功能類似於C#的擴展方法。格式為: @interface Complex(MathOps)

例如:

①現有Complex.h定義:

#import <Foundation/Foundation.h>

@interface Complex : NSObject
@property double real,imaginary;
-(void)print;
-(void)setReal:(double)r andImaginary:(double) m;

@end

Complex.m

#import "Complex.h"
//static int gCount=0;
@implementation Complex
@synthesize real,imaginary;
-(void)print
{
NSLog(@"%g + %gi",real,imaginary);
}
-(void)setReal:(double)r andImaginary:(double)m
{
real=r;
imaginary=m;

}

@end

②現在想擴展Complex類,如下:

Complex+MathOps.h

#import <Foundation/Foundation.h>
#import "Complex.h"
@interface Complex(MathOps)
-(Complex *)add:(Complex *)c;

@end

Complex+MathOps.m

#import "Complex+MathOps.h"
@implementation Complex(MathOps)
-(Complex *)add:(Complex *)c
{
Complex *result=[[Complex alloc] init];
    result.real=self.real+c.real;
    result.imaginary=self.imaginary+c.imaginary;
return result;
}

@end

main.m調用:

#import "Complex.h"
#import "Complex+MathOps.h"
int main(int argc,const char * argv[])
{
@autoreleasepool {
        Complex *c1=[[Complex alloc] init];
        [c1 setReal:1 andImaginary:2];
        Complex *c2=[[Complex alloc] init];
        [c2 setReal:3 andImaginary:4];

        Complex *c3=[c1 add:c2];

        [c3 print];//4 + 6i

    }
return 0;

}

這樣我們就為原有的Complex類新增了add方法。

2.協議 

protocol定義一組方法,它是不屬於具體某個類的,可以被任意類實現,類似於C#中的接口interface。

①定義protocal

使用@protocol指令,后面跟上協議名稱,以@end指令結束。

例如:

MathProtocol.h

#import <Foundation/Foundation.h>

@protocol MathProtocol

-(id)add:(id)v;

@optional
-(id)subscribe:(id)v;

@end

其中@optional指令表示其后面的方法是可選的。

②實現protocol

在@interface行使用尖括號<>,其中加上協議的名稱,然后在.m文件中實現協議中的方法即可。

Complex11.h

#import <Foundation/Foundation.h>

#import "MathProtocol.h"

@interface Complex11 : NSObject<MathProtocol>

@property int real,imaginary;
-(void)setReal:(int)r andImaginary:(int)m;

@end

Complex11.m

#import "Complex11.h"

@implementation Complex11
@synthesize real,imaginary;
-(void)setReal:(int)r andImaginary:(int)m
{
real=r;
imaginary=m;
}
-(Complex11 *)add:(Complex11 *)v
{
Complex11 *result=[[Complex11 alloc] init];
    result.real=self.real+v.real;
    result.imaginary=self.imaginary+v.imaginary;
return result;
}

@end

main.m

#import "Complex11.h"
int main(int argc,const char * argv[])
{
@autoreleasepool {
       Complex11 *c=[[Complex11 alloc] init];
        [c setReal:1 andImaginary:2];
       Complex11 *c2=[[Complex11 alloc] init];
        [c2 setReal:3 andImaginary:4];
       Complex11 *result=[c add:c2];
       NSLog(@"%i +%ii",result.real,result.imaginary);
       //檢查是否遵循某項協議
       bool isprotocol=[c conformsToProtocol:@protocol(MathProtocal)];
       if(isprotocol==YES){
              NSLog(@"c confirm protocol MathProtocol");
        }
    }
return 0;

}

要想判斷一個對象是否遵守某項協議,可以使用confirmsToProtocol方法。


免責聲明!

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



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