zoukankan      html  css  js  c++  java
  • Xcode及objc的基础知识

     1, 从简单的例程来看基本语法:

            下面的代码是通过OSX-Application-Command Line Tool生成的:

            #import <Foundation/Foundation.h>

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

                @autoreleasepool {

                    // insert code here...

                    NSLog(@"Hello, World!");

                    NSLog(@"Hello, Objective-c");

                 }

                return 0;

            }

        1>,文件名:First_OSX_eg.m 这个是OC专用的扩展名,c语言的扩展名一般是用.c,库文件用.h;c++的扩展名一般用.cpp;

             而OC的扩展名都是用.m(来自单词message)不过这个只是阐述部分的扩展名,声明部分的扩展名也是用.h,而且文件名与对应.m的文件是同名,如果扩展名为.mm则可以认为这个单元是c++代码(c++是兼容c的).

        2>,#import相当于C语言中的#include,Delphi语言中的Uses,表示对库文件或其他单元的引用.虽然OC也兼容#include,但是#import要比#include好得多,不管你在文件中出现了多少次#import引用,编译器对特定文件就只引用一次.

            #import之后所用的库文件,在语法上,使用双引号或者尖括号都是允许的,但是一般系统默认为双引号为本地头文件,

    而尖括号里跟的时系统头文件.

        3>,<Foundation/Foundation.h>表示引用Foundation框架中的Foundation.h文件.用花键+单点可以查看对应的单元文件.其实,在引用系统库时,一般头

             文件都是几十上百个头文件的集合.#import可以预编译头文件,使得引用速度加快. 例如Foundation.h对应的框架文件可以在以下路径进行查看:

             /System/Library/Frameworks/Foundation.framework/Headers/  (后面版本的Headers目录改成了Resources目录).

         4>,NSLog函数,其中NS表示OSX中基础Cocoa库,最早引用于Next-Step架构,其意义和用法基本等同于C语言中的printf(),但是其参数需要一个Cocoa库

             格式的字串.类似这样的NS命名的函数还很多,例如:

             NSArray: 用来定义一个数组

             NSDateFormat: 格式化日期

             NSThread:定义一个线程.

             NSSpeechSyntheSizer:定义一个声音.

         5>,用@“xx”来表示一个字串,其中@的意义是指这个字串是一个Cocoa库中的NSString字串,而不是传统的C语言字串.作为一个Cocoa风格的字串,其功能

             要比传统的C语言字串强大得多.例如用StringWithFormat方法就可以用格式化字符(例如%d)格式化各种类型数据.

         6>,花+~可以很方便的在多个工程中切换.

    2, 常用的OC对象类型: 

           1>,UIView : 所有可视控件的基类。基于此类的每一个对象都是一个容器。

            

           2>,UILabel:标签类

           

           3>,UITextField:文本输入类

           

      

           4>,UIButton: 按钮类

           

    3, 常用的OC语法:

           1>程序流程控制

            a>, 选择结构:

                 if(BOOL表达式)

                 {

                     表达式;

                 }

                 else

                {

                    表达式;

                }

            b>,循环结构:

               int i;

               for(i=0; i<=99;i++)

               {

                    NSLog(@“%d\n”,i);

               }

              或者 

              while(BOOL表达式)

              {循环体}; //这个需要在循环体中对BOOL表达式进行控制.

            c>,分支结构:

               switch(表达式)

               {

                   case 分支1数值: 表达式;

                          break;

                   case 分支2数值: 表达式;

                          break;

                   …

               }   

    ’       2>, 函数定义:(注意,在Obj-c中,不允许在一个函数内部直接定义子函数.每个函数的作用范围自动是从

                  上至下,可以通过声明来作用全局,或者提供给其他单元接口),函数允许参数名与函数名同名.

                如果函数的返回值类型为一个类的对象,则函数应该用指针型,例如:

            NSString *ShowMsg(int x1)

            {

                return([NSString stringWithFormat:@"%d",x1]);

            }

                如果是调用这个函数返回值,可以用%@格式字串例如:

               NSLog(@"%@",ShowMsg(123456));

           关于默认的main函数定义:int main(int argc, const char *argv[])

              其中,argc为程序的参数个数,argv为参数数组,其中argv[0]为程序文件本身路径+文件名(这点与Delphi相同).

            3>,  数据类型的定义(对于对象的定义一律用指针)

              a>, 整型: int a;

              b>, 字符类型: char c;

              c>, 字符串类型: 

                   char s[n]; 这个相当于n长度的数组,而对应Cocoa库则为NSArray. 这里s即为一个指针,相当于字符串对象名.

                   char s[]; 可以这么定义一个变长的数组,Obj-c中的字符串严格按对象处理,不像Delphi中那么方便了. 

                   可以用strlen(s)来返回一个字串的长度.

                   char *s[];可以用这个来定义一个多维数组,其中每一个s[i]对应一个字串.

                   NSString str; 不过由于Obj-c中常使用Cocoa库的NSString,所以大多数时候,尽量使用这个类型,它带有很多方便的方法.

              d>,BOOL类型: OC的布尔类型并不是true和false,而是YES和NO. 其本质是一个8位的带符号的字符.定义时,1为YES,0为NO.在实际使用时,如果把其他符号

                    当作BOOL类型判断,那么只会判断其最低位的值,而忽略高位值(注意这里跟C语言不同,并不是大于0就为真).

                    对BOOL类型值的判断,只能拿值与NO进行比较,如果相当为假,不等则为真.无法用BOOL类型与YES进行比较(虽然有时候用YES比较也恰好正确).   

              e>,浮点型float

              f>,常量关键字const 这个可以加在定义类型前,例如:const char *argv[];

              g>,枚举类型的定义:

                  typedef enum{ 枚举常量列表,逗号隔开} 枚举类型名;

                  并没有具体的内部函数可以直接得到枚举常量名,可以自己构造一个函数来实现.

                  常用的枚举定义技巧,可以定义一个起始量和一个终止量,这样方便循环遍历.

              h>,结构体类型定义: 

                  typedef struct{结构体元素定义}结构体类型名;

                  对结构体赋值可以直接用大括号包含数值: stru1={1,’a’};

                  也可以用[结构体变量名.成员名]引用每一个成员进行赋值.

            5>,更为复杂的一些Cocoa定义的有用数据类型.

                a>NSRange:

                typedef struct _NSRange{

                         unsigned int location;

                         unsigned int length;

                 } NSRange;

                 表示一段数据的起始位置以及数据长度.

                 可以利用快捷函数NSMakeRange()来返回一个NSRange

                 eg. NSRange range=NSMakeRange(17,4);

                 b>若干几何数据类型:NSPoint, NSSize,NSRect

                 对应快捷函数NSMakePoint(), NSMakeSize(),NSMakeRect()

                typedef struct _NSPoint{

                          float x;

                          float y;

                 } NSPoint;

                 typedef struct _NSSize{

                          float width;

                          float height;

                 }NSSize;

                 typedef struct _NSRect{

                           NSPoint origin;

                           NSSize size;

                 }NSRect;

                 c> NSString, 相比c语言中的字符串与字符数组的关系,不需要再考虑0操作字符.

                

            6>, 文件类型定义: FILE *words;  words=fopen(argv[1],”r”);   

                  上面这两句也可以在定义时直接赋值:FILE *words=fopen(argv[1],”r”);   

                  fgets(word, 100, words);  这个函数用来读取一个文本文件内容,其中word为一个数组用来接收数据,100读取长度,words为文件类型.

                  其返回值为BOOL型,读取文件时,遇到换行符自动结束本次读取,并且将文件的位置标志置于下行开始.

                  可以用这个语句将读取的内容转为字符串:word[strlen(word)-1]=‘\0’; 反斜杠0是空操作字符用来表示字符串结束.

                  文件标准路径的写法:/Users/Murphy/…

          每一个用户,均有以用户名命名的根目录文件夹结构,其对应的系统文件夹路径如下: 

          公共:/Users/用户名/Public

          图片:/Users/用户名/Pictures

          文稿:/Users/用户名/Documents

    5,类与对象的使用

            1> 类的定义,可以分为两个部分,一个部分是声明部分,一个部分是阐述部分:

             //声明部分用来描述定义各个成员和方法,格式如下:

             @interface 类名 :基类名  //这里基类名可以使用NSObject, 或者其他基类。

             {    

                  @public/@private/@protected  //其实Obj-c并不存在真正的私有方法.这是Obj-c的动态本质决定的.

                  成员定义区;  

             }

             @public/@private/@protect

             方法定义区;     //方法可以用加号或者减号来对应类方法或者成员方法.如果没有加减号,则是函数原型.

             e.g. -(void) setmember : (类型)参数;

             @end

    ’     //类的声明部分主要是针对其方法进行的,格式如下:

            @implementation 类名

            -(void)方法名 : (类型)参数

            {

                方法实现;

            }

           @end  //类名  在结束符后,添加类名,是一个好的习惯,可以增加程序的可读性.

              这里注意,方法的返回值也是需要类型定义的,一定要用加减号(类型)的形式来说明,括号不能省略.同样,参数的

              类型圆括号也不能省略.

              在@implementation中允许出现无声明的方法,这种方法可以看做是类私有方法(与Delphi相同).

              在@implementation部分的参数名可以不与@interface部分相同.注意,在@implementation中使用的参数

              最好不要与@interface部分的成员变量同名,否则会隐藏实例变量,并生成警告信息.

              如果想调用隐藏的实例变量可以用self->成员名来进行.

           2>类和对象的使用语法:

              a> 在Obj-c中,所有对象的原基类都是NSObject,(这相当于Delphi中的Object).

              b>Obj-c中的所有成员变量的定义,均是 类型名在前,变量名在后.并且在定义的时候就可以直接赋值.

              c>Obj-c的中缀符调用方法:

                 [对象名 方法名: 参数];

                 这里方法名和冒号可以看成是一体的,它告诉编译器后面会出现参数.而在不含参数的方法后面添加冒号会报错.

              d>类的公共接口称为API(application programming interface)

              e>在方法体中,允许使用self来访问对象本身.

              f>NSObject类具有一个类方法new,(相当于Delphi的构造方法).我们可以通过调用这个方法得到一个实例.

                 [类名 new];   // 当然所有类方法,都可以用向类名发送消息的方法进行调用.

              g>id 可以用来定义一个通用对象变量,它可以指向任何对象,并且可以用id 来定义一个数组,然后每个数组元素

                 都指向不同类的对象.  //这里有个疑问,为什么不直接用NSObject代替id,不过我好好研究了下,发现id跟Delphi

                 中引用Object还真是不同,id 定义的对象,你可以直接向它发送各种子类消息,而不需要用as 进行类转换.

           3>类继承的实现:

               a>Obj-c废弃了C++多继承的特性,在Obj-c中是不允许多继承的.(这点跟Delphi是一样的).

               b>Obj-c在声明的时候,是没必要像Delphi那样用virtual或者dynamic来声明虚函数的.

                   只需要在子类覆盖此方法的时候,在阐述部分使用super关键字,即可完成继承.其调用父类部分格式为:

                   [super 方法名称:参数];  //即完成了对父类虚方法的调用,类似Delphi中的inherited; 但是这个语句是写在覆盖

                   函数之外的.

                   super关键字,会沿着超类链持续往上级查找,直到找到父类的方法.

           4>类的复合:

               将若干个对象组合在一起,并且形成一个新对象的过程就叫复合.

               每一个组合子对象都可以看作是母对象的一个属性,而对每个属性都可以用同名的getter和setter方法来进行

               存储,一般都是成对出现,其格式如下:

              -(子对象类*) 子对象名;  //这里省略掉了对应的get关键字,除非getter方法需要用到指针形参才会添加get

              -(void) set子对象名:(子对象类型*) new子对象名; //这里的形参最好不要与原对象同名,

               set后跟的对象名,第一个字母一般习惯大写.

              注意,当使用setter方法进行属性设置时,被替代的数据其实是属性的指针,而不是真实值.由于Obj-c的对象引用

              机制,我们不需要考虑到这里的主动释放,这跟Delphi是不同的.

              属性的自我构造,可以使用init函数来实现,在定义属性类中,用以下语句可以实现属性对象的自我构造:

              注意init方法属于对象的内部方法,是不需要在@interface部分主动声明的.

              @implementation 母对象名

              -(id)init

              {

                  if(self=[super init]){

                      属性名=[属性类名 new];

                  }

                  return(self);

              }//init

              …

              @end

              这样就形成了属性的自我构造,不过如果属性有相应的setter方法,其实不用构造也可以,不过使用时需要主动赋值.

           5>头文件的拆分,指向,导入和继承:

               在用.m文件和.h文件拆分复合类时,需要在复合类的头文件中用  @class 类名  指向其复合的属性类.

               而在复合类的阐述文件中,不仅仅要用#import导入其对应头文件,也必须用其导入对应的所有属性类的头文件.

               而在派生类拆分文件时,派生类的头文件,只需要导入父类的头文件就可以(可以完全忽略父类中已有的系统头文件)

           6>面向对象的设计意义:

               a>在面向对象和面向过程的设计中,最大得差别是其功能修改增删时的改变方式.面向对象可以避免修改到整体

                  的处理函数,也不需要修改基本的结构体,只需要增加一个类基本就可以适应变化了.

               b>面向过程的设计是函数第一,数据第二,这导致程序修改经常会影响到接口;而面向对象的设计,可以直接吧原先

                  函数修改的部分巧妙的移动到对象的方法之中,我们只需要关注对象这个数据就好了,不会影响到函数和接口.

               c>当不同类中出现了大量的重复的代码,就绝非优良的设计,我们可以更改其类的继承结构,使这些重复代码在中间

                  的继承类中实现,这种移动和简化代码的方法称为重构.

               d>当你创建的新类与现有类是is a 的关系就可以使用继承;当你创建的类与现有类是has a 的关系,就需要用到复合了.

            7>面向对象的术语:

                a>超类:superclass

                b>父类:parentclass,同超类.

                c>子类(派生类):subclass

                d>孩子类:childclass,同子类.

    6,常用的XCode操作技巧

         1>花+[ 和 花+]可以将选定得代码块左移或者右移

         2>ESC键可以关闭和打开自动完成的选择框.

         3>Control+/ 可以在输入时自动跳在占位符上.

         4>花+Control+S可以建立一个快照.

         5>花+Shift+O 快速打开一个单元文件.

         6>Control+F/B 分别是前移光标和后移光标.

         7>Control+P/N 分别是上移光标和下移光标.

         8>Control+A/E 分别是移动光标到该行的行首和行尾.

         9>Control+T 把光标前的字符往后拖一个位置.

         10>Control+D 删除光标右边的字符(相当于windows中的Del键).

         11>Control+K 删除一行.其实这个是删除当前行光标后面的部分.

         12>Control+L 调整窗口,以便将当前的光标居于窗口中心.

         13>花+Y 以调试方式运行程序.

         14>花+Option+P/O/I/T  分别是调试的 继续,跳过,跳入,跳出.

         

          

            

        

    不求功能强大,但求小巧融洽
  • 相关阅读:
    ActiveMQ (一) 简介
    MSMQ .NET下的应用
    MSMQ
    RabbitMq C# .net 教程
    Rabbit MQ
    Dynamics 365—脚本
    DNS服务器地址汇总
    特殊字符 编码
    4s前置摄像头调用
    登陆前后导航栏处理 2015-12-12
  • 原文地址:https://www.cnblogs.com/Murphieston/p/5260045.html
Copyright © 2011-2022 走看看