美文网首页
Objective-C

Objective-C

作者: 帽子和五朵玫瑰 | 来源:发表于2018-05-16 10:24 被阅读0次

    c和OC

    1.程序运行时,计算机会将相应的文件复制到内存(RAW)中去,执行文件中的命令。

    2.不同CPU,汇编语言不同

    3."高级语言",不考虑特定CPU,使用统一的方法发布指令,然后由编译器来将这些代码转换成经过高度优化的,针对特定CPU的机器编码。

    4.OC是以C为基础的,增加了对面向对象编程的支持。

    Xcode

    1.有些程序没有图形化的用户界面,但可以长时间运行,称之为守护进程(daemon)。比如复制粘贴时就用到了pdoard。

    2.还有只能在相爱terminal上运行的程序,称之为命令行工具。

    3.C语言编写完成程序后,编译器会将程序转换成机器吗,当点击run按钮时,Xcode会运行这个编译器(编译器也是一个程序)。此处的(编译一个程序)和(构建一个程序)值的是一件事。

    4.运行程序时,计算机会将变异后的程序从硬盘拷贝至内存,然后处理器会执行程序的main函数,main函数会再调用其他函数。

    函数

    5.1计算机在运行程序时,会将这些函数从硬盘拷贝至内存,然后找到名为“main”的函数并执行。

    5.4 标准库
    其中一些文件包含一组预先编译过的函数。这些组文件被称为标准库(standard libraries)。

    标准库由多个文件构成,其中两个文件为stdio.h及unistd.h

    如果在你的程序中包含这两个文件,就可以使用文件中包含的函数,例如stdio.h文件中的printf()函数,以及unistd.h中的sleep()函数

    标准库有两大作用:

    1.包含大量程序员无需自己编写和维护的代码。与自己编写的代码相比,使用标准库可以构建出更复杂,更好的程序。

    2.确保大多数程序有相当的共通性。

    5.5帧(frame)和栈(stack)

    帧可以用来保存函数执行时的数据,当函数执行结束后,帧被销毁。

    A函数中,调用的B函数,当运行时,B函数被调用了,A函数在等待B函数,这时,A函数存在于栈中

    栈用来描述帧在内存中的存贮的地点,执行函数时,函数的帧会在栈的顶部被创建出来。函数执行结束时,我们会说函数返回了,也就是说,其帧会退出栈。等待下一个调用他的函数继续执行。

    格式化字符串

    printf("It was the best of times.\n");
    
    char *str = "It was the best of times.\";
    printf(*str);
    
    //这两者是一样的
    

    1.格式说明符

    char *str = "It ";
    printf("这个是%s。\n",str );
    //str中的内容会替换%s
    

    %s == 数据类型是一个字符串

    %d == 数据类型是一个整数

    2.转义字符

    \n 转义字符 换行

    整数

    1.整数

    UInt32 x; //无符号32位整数
    SInt16 y; //有符号16位整数
    char a;//8位
    short b;//一般是16位
    int c;//一般是32位
    long d;//32位或64位,视平台而定
    long long e;//64位
    
    int x =255
    printf("x is %d.\n", x); //十进制输出
    printf("x is %o.\n", x);//八进制
    printf("x is %x.\n", x);//十六进制
    x is 255
    x is 377
    x is ff
    

    NSInteger NSUInteger有符号,无符号

    int i =3;
    while (i<12){
        char s = "qqqq"
        printf("%s\n",s );
        i++;
    }
    for(int i=0;i<10;i++){
        printf("qqqq\n");
    }
    do{
        char s = "qqqq"
        printf("%s\n",s );
        i++;
    }while(i<12);
    

    break跳出整个循环

    continue 跳出余下,执行下一次循环。

    9地址和指针

    9.1获取地址

    变量的地址,是指内存中的某个位置,该位置的内存保存着变量的值,通过&运算符,可以得到变量的地址。

    int i =17;
    printf("i stores its value at %p\n",&i );
    

    i stores its value at 0xbffff738

    任何一个函数都有自己的地址,通过函数的函数名,就能得到相应函数的地址

    printf("this function starts at %p\n",main );
    

    9.2用指针保存地址

    只要是大小合适的无符号整数,就可以保存指针。

    当数据很大很复杂时,指针的好处就体现出来了。这是因为程序不一定能通过拷贝来传递数据,但是一定能够直接传递或通过拷贝来传递数据的起始地址。

    9.3通过地址访问数据

    使用*运算符,可以访问保存在某个地址中的数据。

    int i =17
    int *add = &i;
    

    9.4不同类型数据所占字节大小

    sizeof()可以得到某个数据类型的大小

    sizeof(int)

    sizeof(*int)

    9.5 NULL

    使用空指针,不指向任何地址。有一个能够保存地址的指针变量,但是要赋上某个值,用于明确表示该指针没有指向任何地址。

    9.6代码规范

    float power 而不是 float power

    float a,b,c;都是float

    float *a,b;a是指针,b是float

    float a,b;都是指针

    通过引用传递

    C语言标准库中有一个modf()函数,调用该函数并传入一个都变了的数,可以得到浮点数的整数部分和小数部分。例如3.14。可以得到整数部分3和小数部分0.14

    调用modf()函数时,需要传入一个地址供modf()函数保存整数部分的计算结果,准确的说,modf()会返回小数部分,然后将整数部分拷贝至传入的地址。

        double pi =3.14;
        double integerPart;
        double fractionPart;
        
        fractionPart = modf(pi,&integerPart);
        
        printf("integerPart = %.0f,fractionPart = %.2f/n",integerPart,fractionPart);
        
    

    编写通过引用传递参数的函数

    void metersToFeetAndInches(double meters,unsigned int *ftPtr,double *inPtr){
        double rawFeet = meters * 3.281;
        unsigned int feet = (unsigned int)floor(rawFeet);
        *ftPtr = feet;
    
        double fractionFoot = rawFeet - feet;
        double inches = fractionFoot *12.0;
        *inPtr = inches;
    }
    
    double meters = 3.0;
    unsigned int feet ;
    double inches;
    metersToFeetAndInches(meters,&feet,&inches);
    

    不要对NULL取值

    结构

    编写程序时,需要一个变量保存多个数据

    struct  Person
    {
        float heightInMeters;
        int weightInKilos;
    };
    int main(int argc, char const *argv[])
    {
        struct Person mikey;
        mikey.heightInMeters = 1.7;
        return 0;
    }
    

    在声明类型为结构的变量时,每次都要用Stuct这样很麻烦。

    可以用typedef

    typedef struct{
        float heightInMeters;
        int weightInKilos;
    } Person;
    int main(int argc, char const *argv[])
    {
        Person miki;
        return 0;
    }
    

    前几章使用的都是栈中的内存,这类内存空间会在调用函数时由系统自动分配,并在函数结束之后自动释放。这也是局部变量常被称为自动变量的原因。

    仅有自动变量是不够的,有时还要“申请”一块连续的内存-缓冲区(buffer)。编程术语中的缓冲区常被用来表示一块连续的内存,缓冲区来自特定的内存区域--堆(heap)

    在堆上,缓冲区独立于任何函数的栈,因此,他可以在多个函数中使用。例如,你可以声明一个缓冲区存储一些文本文件,然后调用某个函数将文本文件保存至缓冲区中。再点用另一个函数来统计文本中字母的个数,最后在调用一个函数来进行校对。处理完文本文件之后,就可以将缓冲区的这块内存还给堆。

    使用malloc()函数可以得到一块内存缓冲区。当程序不再使用这块缓冲区时,可以调用free()函数,释放相应的内存,将其返还给堆

    int main(int argc, char const *argv[])
    {
        float *startOfBuffer;
        startOfBuffer = malloc(1000*sizeof(float));
        free(startOfBuffer);
        *startOfBuffer = NULL;
        return 0;
    }
    
    typedef struct{
    float a;
    int b;
    }Person;
    float bodyMassIndex(Person *p){
        return p->a/(p->a+p->b);
    }
    int main(int argc, char const *argv[])
    {
        Person *mike = (Person *)malloc(sizeof(Person));
        mike->a = 12.2;
        mike->b = 333;
        free(mike);
        mike = NULL;
        return 0;
    }
    

    对象

    import和#include区别

    import指令导入更快更有效率,会让编译器先检查之前是否已经导入过这个文件

    include指令告诉编译器做呆板的复制粘贴

     import <Foundation/Foundation.h>
    
     int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
            NSDate *now = [NSDate date];
        }
        return 0;
    }
    

    详解消息

    给新对象发送消息,比如发送timeIntervalSince1970

    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
            NSDate *now = [NSDate date];
            NSLog(@"This NSDate object lives at %p",now);
            NSLog(@"This date is %@",now);
            double secondes = [now timeIntervalSince1970];
            NSLog(@"it has been %f seconds since the start 1970",secondes);
        }
        return 0;
    }
    

    发送错误消息

    区分大小写

    命名习惯

    方法名第一个单词小写开头,后面的单词大写开头

    类的名称大写字母开头,接下来的单词也大写开头

    再谈消息

    14.1传递实参消息
    接受方                         实参
      |                              |
     \_/                            \_/
    [now dateByAddingTimeInterval:100000]
                 /-\
                  |
                选择器
    
    14.2多个实参
    接受方                         实参
      |                              |
     \_/                            \_/
    [cal ordinalityOfUnit:NSDayCalendarUnit
                   inUnit:NSMonthCalendarUnit
                  forDate:now]
                 /-\
                  |
                选择器
    
    14.3消息的嵌套发送
    NSDate *now = [NSDate date];
    double seconds = [now timeIntervalSince1970];
    //也可以嵌套起来
    double seconds = [[NSDate date] timeIntervalSince1970]; 
    
    14.4 alloc和init

    唯一必须使用嵌套的形式连续发送的消息是alloc和init

    每个类都有一个alloc类方法。它能够创建一个新的对象,并返回指向该对象的指针。通过alloc创建出来的对象,必须经过初始化才能使用。如果创建出来的新对象没有经过初始化,它会存在于内存里,但是无法接受消息。每个类也都有一个init实例方法,它用来初始化实例。

    NSDate *now = [[NSDate alloc]init];
    
    14.5向nil发送消息

    几乎所有的面相对象的语言都会有nil这样的概念:不指向任何对象的指针。在Objective-C中,nil的值为0的指针。

    多数面向对象的语言不允许向nil发送消息。所以在发送消息前,必须检查指针是否为nil,从而导致出现大量下面这类代码:

    if(fido!=nil){
        [fido foGetTheNewspaper];
    }
    

    OC则不同,在OC中,可以向nil发送消息。什么事情也不会发生。因此下面这段代码是合法的:

    Dog *filo =nil;
    [filo goGetTheNewsPaper];
    

    <font color=#0099ff size=12 face="黑体">重点1:</font>如果程序向某个对象发送了消息,但却没有得到预期的结果,请检查消息接受方是否为nil。

    <font color=#0099ff size=12 face="黑体">重点2:</font>向nil发送消息,得到的返回值没有意义

    14.6 id

    当声明指向对象的指针式,通常都会明确地写出相应对象的类:

    NSDate *expiration;

    但是在编写程序是,很可能会碰到以下这种情况:声明指针时并不知道所指对象的准确类型。为此,可以使用id类型。id类型的含义是:可以指向任意类型Objective-C对象的指针

    再谈消息

    14.1传递实参消息
    接受方                         实参
      |                              |
     \_/                            \_/
    [now dateByAddingTimeInterval:100000]
                 /-\
                  |
                选择器
    
    14.2多个实参
    接受方                         实参
      |                              |
     \_/                            \_/
    [cal ordinalityOfUnit:NSDayCalendarUnit
                   inUnit:NSMonthCalendarUnit
                  forDate:now]
                 /-\
                  |
                选择器
    
    14.3消息的嵌套发送
    NSDate *now = [NSDate date];
    double seconds = [now timeIntervalSince1970];
    //也可以嵌套起来
    double seconds = [[NSDate date] timeIntervalSince1970]; 
    
    14.4 alloc和init

    唯一必须使用嵌套的形式连续发送的消息是alloc和init

    每个类都有一个alloc类方法。它能够创建一个新的对象,并返回指向该对象的指针。通过alloc创建出来的对象,必须经过初始化才能使用。如果创建出来的新对象没有经过初始化,它会存在于内存里,但是无法接受消息。每个类也都有一个init实例方法,它用来初始化实例。

    NSDate *now = [[NSDate alloc]init];
    
    14.5向nil发送消息

    几乎所有的面相对象的语言都会有nil这样的概念:不指向任何对象的指针。在Objective-C中,nil的值为0的指针。

    多数面向对象的语言不允许向nil发送消息。所以在发送消息前,必须检查指针是否为nil,从而导致出现大量下面这类代码:

    if(fido!=nil){
        [fido foGetTheNewspaper];
    }
    

    OC则不同,在OC中,可以向nil发送消息。什么事情也不会发生。因此下面这段代码是合法的:

    Dog *filo =nil;
    [filo goGetTheNewsPaper];
    

    <font color=#0099ff size=12 face="黑体">重点1:</font>如果程序向某个对象发送了消息,但却没有得到预期的结果,请检查消息接受方是否为nil。

    <font color=#0099ff size=12 face="黑体">重点2:</font>向nil发送消息,得到的返回值没有意义

    14.6 id

    当声明指向对象的指针式,通常都会明确地写出相应对象的类:

    NSDate *expiration;

    但是在编写程序是,很可能会碰到以下这种情况:声明指针时并不知道所指对象的准确类型。为此,可以使用id类型。id类型的含义是:可以指向任意类型Objective-C对象的指针

    相关文章

      网友评论

          本文标题:Objective-C

          本文链接:https://www.haomeiwen.com/subject/iptpdftx.html