zoukankan      html  css  js  c++  java
  • ObjectiveC: 变量和数据类型:初始化方法、外部/静态变量、枚举类型、typedef、类型转换、位运算符

    初始化方法

    初始化对象和设置初始值的过程通常可以合并到一个方法中,常见变成习惯是类中所有的初始化方法都以init开头。

    包含很多方法和实例变量的类通常还有几个初始化方法。例如Foundation框架中的NSArray类包含6个额外的初始化方法:

    initWithArray:、initWithArray:copyItems:、initWithContentsOfFile:、initWithObjects:、initWithObjects:count:。

    可使用myArray[[NSArray alloc] initWithArray: myOtherArray]; 完成数组的空间分配和初始化工作。

    编写初始化方法时应遵循两个策略:

    1. 如果希望在类对象初始化时做一些事情(如Rectangle类初始化时需要为矩形指定XYPoint原点),可以通过重载init方法达到目的。

      //重载init方法标准模板
    - (instancetype) init {
    self = [super init]; //调用父类初始化方法,使继承的实例变量能够正常初始化
    //注意必须将父类init方法的执行结果赋值给self,因为初始化过程改变了对象在内存中的位置(引用将要改变)
        if(self) { //如果父类初始化成功,返回值将是非空的
            //自定义初始化代码,通常可以再这个位置创建并初始化实例变量
        }
        return self
    }

    2. 如果你的类包含多个初始化方法,其中一个就应该是指定的(designated)初始化方法,通常是最复杂的初始化方法(一般是参数最多的初始化方法),并且其他所有初始化方法都应该使用这个方法。可以把大部分初始化代码几种到单个方法中,任何人想要从这个类派生子类,都可以重载这个指定的初始化方法,保证正确地初始化新的实例。

    例:

    //为Fraction类添加初始化方法initWith:over:
    -(Fraction *)initWith:(int)n over:(int)d {
        self = [super init];
        if (self)
            [self setTo: n over: d];
        return self;
    }
    //使用初始化方法initWith:over:
    a = [[Fraction alloc] initWith:1 over:3];
    b = [[Fraction alloc] initWith:3 over:7];

    为使用指定的初始化规则,需要修改Fraction类的init方法:

    -(instancetype) init { //返回为instancetype类型,是编写可能会被继承的类init方法的一般规则
        return [self initWith:0 over:0];
    }

    外部变量:可以被其他任何方法或函数访问和更改的值,只要在需要访问外部变量的模块中用关键字extern声明变量,告知系统要访问其他文件中定义的全局变量。如:

    int gMoveNumber = 0; /*变量必须不加关键字extern定义在源文件中的某个位置(在所有方法和函数外)*/
    extern int gMoveNumber; //包含该声明的模块可以访问和改变gMoveNumber的值

    如果很多方法需要访问该全局变量的值,则只在文件开始进行一次extern声明比较简便;如果只有一个或少数几个方法要访问该全局变量,则应该在其中的每个方法中单独进行extern声明(程序组织结构更清晰、不同函数可以单独使用这个变量);如果变量定义在包含访问这个变量的文件中,则不需要单独进行extern声明。

     

    静态变量:如果希望定义的全局变量只在特定模块(文件)中是全局的,即除特定类中的方法外,再没有其他方法能够访问这个特定变量,可以在包含这个特定类的实现文件中将该变量定义为static。

    如:

    static int gGlobal;
    /*如果该语句声明在任何方法(或函数)之外,则文件中所有位于该语句之后的方法或函数都可以访问gGlobalVar的值,而其他文件中的方法和函数则不行。*/

    可以通过在类的实现代码文件中设定静态变量,记录类已经分配空间的对象数目。如:

    在Fraction.h中添加两个新的类方法声明:

    +(Fraction *) allocF;
    +(int) count;

    在实现文件Fraction.m中加入定义:

    static int gCounter;
    
    @implementation Fraction {
        int numerator;
        int denominator;
    }
    
    @synthesize numerator, denominator;
    
    /*allocF类方法分配一个新的Fraction对象,同时记录分配了多少Fraction*/
    +(Fraction *) allocF {
        extern int gCounter;
        ++gCounter;
        return [Fraction alloc];
    }
    
    /*count类方法返回记录的数值*/
    +(int) count {
        extern int gCounter;
        return gCounter;
    }
    ...
    @end

    在main.m中测试:

            Fraction *a, *b, *c;
            NSLog(@"Fractions allocated: %i", [Fraction count]); //output: 0 
    /*程序开始时gCounter自动置零,如果需要设定特定计数可在类中添加setter方法*/
            a = [[Fraction allocF] init];
            b = [[Fraction allocF] init];
            c = [[Fraction allocF] init];
            NSLog(@"Fractions allocated: %i", [Fraction count]); //output: 3

    枚举数据类型

    enum flag {false, true} //定义数据类型flag,只能赋为true或false
    enum flag endofDate, matchFound; /*声明enum flag类型的变量 (关键字enum-枚举类型名称-变量序列)*/

    如果希望一个枚举标识符对应一个特定整数值,可在定义数据类型时给标识符指定整数值,列表中随后出现的枚举标识符依次+1赋整数值。如:

    enum direction {up, down, left = 10, right}; //up=0, down=1, left=10, right=11

    枚举标识符也可以共享相同的值。

    Objective-C编译器实际上将枚举标识符作为整型常量处理。如:

    enum month {January = 1, feburary, march, april, may, june, july, august, september, october, november, december};
    enum month thisMonth;
    thisMonth = feburary; //赋给thisMonth的值为整数2

    但尽量不要依赖枚举值被作为整数的事实,应该将枚举数据类型当做独立的数据类型。

    定义枚举类型时可以将一个整数类型和一个枚举名称对应起来。如:

    enum iPhoneModels : unsigned short int {iPhone, iPhone3G, iPhone3GS, iPhone4, iPhone4s, iPhone5,
                                iPhone5C, iPhone5S); /*使用unsigned short int作为相关数据类型*/

    定义枚举类型时也允许省略数据类型名称,将变量声明为特定枚举数据类型中的一个。如:

    /*定义未命名枚举数据类型(包含值为east、west、south和north),同时声明该类型的变量direction*/
    enum {east, west, south, north} direction; 

    typedef语句

    使用typedef语句可为数据类型另外指派一个名称。

    typedef int Counter; //定义名称Counter等价于数据类型int,随后变量可声明为Counter类型
    Counter j, n; //编译器实际上将变量j和n的声明当做普通整型int变量声明
    
    typedef Number *NumberObject; //定义名为NumberObject的类型,是Number对象
    NumberObject myValue1, myValue2, myResult; 
    //等价于
    Number *myValue1, *myValue2, *myResult;
    
    typedef enum {east, west, south, north} Direction; //定义名为Direction的枚举数据类型
    Direction step1, step2; //声明Direction类型的变量

    数据类型转换

    表达式求值过程中不同类型操作数发生转换的先后顺序(简化):

    1. 如果其中一个操作数是long double型,则另一操作数被转换为long double型,计算结果也是。

    2. 如果其中一个操作数是double型,则另一操作数被转换为double型,计算结果也是。

    3. 如果其中一个操作数是float型,则另一操作数被转换为float型,计算结果也是。

    4. 如果其中一个操作数是Bool、char、short int、bit field或枚举数据类型,则全部转换为int型。

    5. 如果其中一个操作数是long long int型,则另一操作数被转换为long long int型,计算结果也是。

    6. 如果其中一个操作数是long int型,则另一操作数转换为long int型,计算结果也是。

    7. 如果到达这一步,则可知两个操作数均为int型,计算结果也是。

     

     

    位运算符

    位运算符除一次求反运算符(~)外都是二元运算符。

    位运算符可处理任何类型的整型值,但不能处理浮点值。

    按位与运算符&的优先级高于按位或运算符|。

  • 相关阅读:
    网页显示UIWebView(一个)
    借百度数据,建立你自己的程序
    引水数据--紧凑
    Unity3d 实时折射和反射
    snmp监控磁盘
    Linux snmp监控
    20监控工具
    Java 四舍五入
    Oracle主键操作
    SnmpTrap
  • 原文地址:https://www.cnblogs.com/RDaneelOlivaw/p/7676605.html
Copyright © 2011-2022 走看看