zoukankan      html  css  js  c++  java
  • 学习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方法。

  • 相关阅读:
    地方坐标系
    地图常用坐标系
    地图投影【百度百科】
    地图投影
    坐标系、坐标参照系、坐标变换、投影变换
    Scale和Resolution的含义及转换算法
    OpenStreetMap/Google/百度/Bing瓦片地图服务(TMS)
    面向对象的一些方法
    对象构造函数的原型图
    bookstarp的初体验
  • 原文地址:https://www.cnblogs.com/janes/p/5391258.html
Copyright © 2011-2022 走看看