zoukankan      html  css  js  c++  java
  • OC 语法快速入门

    来源: https://www.runoob.com/w3cnote/objective-c-tutorial.html

    Interface

    定义部分,清楚定义了类的名称、数据成员和方法。 以关键字@interface作为开始,@end作为结束。

    @interface MyObject : NSObject {
        int memberVar1; // 实体变量
        id  memberVar2;
    }
    
    +(return_type) class_method; // 类方法
    
    -(return_type) instance_method1; // 实例方法
    -(return_type) instance_method2: (int) p1;
    -(return_type) instance_method3: (int) p1 andPar: (int) p2;
    @end
    
    

    方法前面的 +/- 号代表函数的类型:加号(+)代表类方法(class method),不需要实例就可以调用,与C++ 的静态函数(static member function)相似。减号(-)即是一般的实例方法(instance method)。

    这里提供了一份意义相近的C++语法对照,如下:

    class MyObject : public NSObject {
    protected:
        int memberVar1;  // 实体变量
        void * memberVar2;
    
      public:
        static return_type class_method(); // 類方法
    
        return_type instance_method1();    // 实例方法
        return_type instance_method2( int p1 );
        return_type instance_method3( int p1, int p2 );
    }
    
    

    Objective-C定义一个新的方法时,名称内的冒号(:)代表参数传递,不同于C语言以数学函数的括号来传递参数。Objective-C方法使得参数可以夹杂于名称中间,不必全部附缀于方法名称的尾端,可以提高程序可读性。设定颜色RGB值的方法为例:

    - (void) setColorToRed: (float)red Green: (float)green Blue:(float)blue; /* 宣告方法*/
    
    [myColor setColorToRed: 1.0 Green: 0.8 Blue: 0.2]; /* 呼叫方法*/
    
    

    这个方法的签名是setColorToRed:Green:Blue:。每个冒号后面都带着一个float类别的参数,分别代表红,绿,蓝三色。

    在Object-C中,有两种类型的方法,类方法和实例方法。

    类方法以+开头,其基本形式如下:

    (id)someMethod;

    类方法一般都是工厂方法,返回一个实例。

    实例方法以-开头,其基本形式如下:

    - (void)someMethod;

    方法可以不带参数,也可以带一个或多个参数,也可以有返回值:

    (int)someMethod;
    
    (void)someMethodWithValue:(SomeType)value;
    
    (void)someMethodWithFirstValue:(SomeType)value1 secondValue:(AnotherType)value2;
    
    

    1、程序的头文件和源文件的扩展名分别为.h 和.m;

    2、注释:单行(//)和多行(/* … */);

    3、Object_C 中的nil 相当于NULL。

    4、Object_C 中的YES 和NO 相当于true 和false。

    5、#import相当于#include ,导入头文件也有两种查找方式< … > 和" … ",但是#import 可自动防止同一个文件被导入多次。

    6、Object_C中的所有类都必须继承自NSObject。

    7、Object_C仅支持单一父类继承,不支持多重继承。

    8、Object_C中所有对象都是指针的形式。

    9、Object_C用self代替this。

    10、Object_C使用id代替void*。

    11、Object_C中用消息表示类的方法,并采用[aInstance method:argv]调用形式。

    12、Object_C支持反射机制。

    13、Object_C支持Dynamic Typing,Dynamic Binding和Dynamic Loading。

    Implementation

    实现区块则包含了公开方法的实现,以及定义私有(private)变量及方法。 以关键字@implementation作为区块起头,@end结尾。

    @implementation MyObject {
      int memberVar3; //私有實體變數
    }
    
    +(return_type) class_method {
        .... //method implementation
    }
    -(return_type) instance_method1 {
         ....
    }
    -(return_type) instance_method2: (int) p1 {
        ....
    }
    -(return_type) instance_method3: (int) p1 andPar: (int) p2 {
        ....
    }
    @end
    
    

    属性

    属性是用来代替声明存取方法的便捷方式。属性不会在你的类声明中创建一个新的实例变量。他们仅仅是定义方法访问已有的实例变量的速记方式而已。暴露实例变量的类,可以使用属性记号代替getter和setter语法。类还可以使用属性暴露一些“虚拟”的实例变量,他们是部分数据动态计算的结果,而不是确实保存在实例变量内的。

    实际上可以说,属性节约了你必须要写的大量多余的代码。因为大多数存取方法都是用类似的方式实现的,属性避免了为类暴露的每个实例变量提供不同的getter和setter的需求。取而代之的是,你用属性声明指定你希望的行为,然后在编译期间合成基于声明的实际的getter和setter方法。

    属性声明应该放在类接口的方法声明那里。基本的定义使用@property编译选项,紧跟着类型信息和属性的名字。你还可以用定制选项对属性进行配置,这决定了存取方法的行为。下面的例子展示了一些简单的属性声明:

    @interface Person : NSObject {
        @public
            NSString *name;
        @private
            int age;
    }
    
    @property(copy) NSString *name;
    @property(readonly) int age;
    
    -(id)initWithAge:(int)age;
    @end
    
    

    性的访问方法由@synthesize关键字来实现,它由属性的声明自动的产生一对访问方法。另外,也可以选择使用@dynamic关键字表明访问方法会由程序员手工提供。

    @implementation Person
    @synthesize name;
    @dynamic age;
    
    -(id)initWithAge:(int)initAge
    {
        age = initAge; // 注意:直接赋给成员变量,而非属性
        return self;
    }
    
    -(int)age
    {
        return 29; // 注意:并非返回真正的年龄
    }
    @end
    
    

    属性可以利用传统的消息表达式、点表达式或"valueForKey:"/"setValue:forKey:"方法对来访问。

    Person *aPerson = [[Person alloc] initWithAge: 53];
    aPerson.name = @"Steve"; // 注意:点表达式,等于[aPerson setName: @"Steve"];
    NSLog(@"Access by message (%@), dot notation(%@), property name(%@) and direct instance variable access (%@)",
          [aPerson name], aPerson.name, [aPerson valueForKey:@"name"], aPerson->name);
    
    

    为了利用点表达式来访问实例的属性,需要使用"self"关键字:

    -(void) introduceMyselfWithProperties:(BOOL)useGetter
    {
        NSLog(@"Hi, my name is %@.", (useGetter ? self.name : name)); // NOTE: getter vs. ivar access
    }
    
    

    类或协议的属性可以被动态的读取。

    多个属性之间,可以使用逗号分隔:

    @property (strong, nonatomic) UIWindow *window; 属性通常还会加一些修饰,来控制数据的访问和存储等:

    @property (readonly) NSString *firstName;
    @property (readonly) NSString *lastName;
    
    
    

    属性修饰:

    readonly与readwrite:

    readonly表明该属性是只读的,外部不能修改其值。与readonly相对的修饰是readwrite,但你不必把它写出来,因为它是默认的。 atomic与nonatomic:

    (atomic、nonatomic)属性用于多线程编程,属性默认是atomic的。在多线程环境下设置为atomic可以保证数据读取的一致性(因为,它将保证数据仅仅被一个线程独占。也就是说一个线程进行写操作时,将锁定该属性,不允许其他的线程进行写操作。)由于该操作会对数据进行锁操作,故会消耗较多的资源。所以在不需要进行多线程操作时建议将该属性设置为nonatomic,设置为该参数时程序在任何情况都不会锁定该属性。

    strong与weak:

    其中strong是默认的。strong表示该属性对其相应的对象是强引用。一个变量保持对一个对象的强引用,只要该变量在其作用域范围内或者直到它被赋给另一个对象或者nil为止。weak表示对属性对应的对象的弱引用。

    copy、assign、retain:

    copy修饰表示该属性将使用强引用,因为它必须保持它创建的新对象。

    assign指定setter方法用简单的赋值,不更改索引计数(Reference Counting),一般对简单数据类型 使用assign。

    retain,对象引用计数加一。

    快速枚举

    比起利用NSEnumerator对象或在集合中依次枚举,Objective-C 2.0提供了快速枚举的语法。在Objective-C 2.0中,以下循环的功能是相等的,但性能特性不同。

    // 使用NSEnumerator
    NSEnumerator *enumerator = [thePeople objectEnumerator];
    Person *p;
    
    while ( (p = [enumerator nextObject]) != nil ) {
        NSLog(@"%@ is %i years old.", [p name], [p age]);
    }
    
    
    // 使用依次枚举
    for ( int i = 0; i < [thePeople count]; i++ ) {
        Person *p = [thePeople objectAtIndex:i];
        NSLog(@"%@ is %i years old.", [p name], [p age]);
    }
    
    
    // 使用快速枚举
    for (Person *p in thePeople) {
        NSLog(@"%@ is %i years old.", [p name], [p age]);
    }
    
    

    快速枚举可以比标准枚举产生更有效的代码,由于枚举所调用的方法被使用NSFastEnumeration协议提供的指针算术运算所代替了。

    还有一些其他的比如类别,转发 这些都是后面再学也没关系的

  • 相关阅读:
    【Azure 应用服务】在Azure App Service多实例的情况下,如何在应用中通过代码获取到实例名(Instance ID)呢?
    【Azure 应用服务】App Service For Windows 中如何设置代理实现前端静态文件和后端Java Spring Boot Jar包
    【Azure Developer】使用Azure Key Vault 的Key签名后,离线验证的一些参考资料
    【Azure Function】调试 VS Code Javascript Function本地不能运行,报错 Value cannot be null. (Parameter 'provider')问题
    【Azure 应用服务】App Service 使用Tomcat运行Java应用,如何设置前端网页缓存的相应参数呢(Xms512m Xmx1204m)?
    【Azure API 管理】APIM添加Logtoeventhub的策略后,一些相关APIM与Event Hub的问题
    【Azure API 管理】为调用APIM的请求启用Trace 调试APIM Policy的利器
    【Azure 事件中心】China Azure上是否有Kafka服务简答
    【Azure 应用服务】探索在Azure上设置禁止任何人访问App Service的默认域名(Default URL)
    【Azure 微服务】记一次错误的更新Service Fabric 证书而引发的集群崩溃而只能重建
  • 原文地址:https://www.cnblogs.com/Grewer/p/13152374.html
Copyright © 2011-2022 走看看