欢迎访问移动开发之家(rcyd.net),关注移动开发教程。移动开发之家  移动开发问答|  每日更新
页面位置 : > > > 内容正文

Objective-C,

来源: 开发者 投稿于  被查看 44644 次 评论:155

Objective-C,


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对象的指针

相关文章

    暂无相关文章

用户评论