从C++到OC,快速掌握 OC语法

从C++到OC,快速掌握 OC语法

[toc]

学习Objective-C 的笔记,有 C/C++ 基础的同学阅读文章此可以快速掌握 OC。

Xcode 快捷键

格式化代码:Command + A 全选(选中需要格式的代码段) 再 Ctrl + i 格式化代码

C 和 OC 的区别

由于 OC 的底层是 C 语言,所以 OC 和 C 完全兼容,在编程过程中,OC 和 C 可以混合使用。

分析一下一段最基本的 OC 代码:

#import <Foundation/Foundation.h>

int main() {
    NSLog(@"Hello, World!");
    return 0;
}
  • 在 OC 中, #import 命令用来引入头文件。与 C 语言中的 #include 相比,#import 能够保证头文件只被引入一次,也就是说,只有第一次引入有效,后续对同一文件的引入都会被忽略。而在 C 语言中,每次使用 #include 命令都会将头文件的内容引入一次,所以在头文件中必须使用 #ifndef#endif 宏来保证头文件只被编译一次

  • Foundation/Foundation.h 是 Foundation 框架的头文件,只要引入了它,就可以使用 Foundation 框架的功能。

    Foundation 是 OC 语言的基础框架,它提供了 OC 专有的基本数据类型(如字符串、数组、时间日期等),提供了多线程、网络连接、文件操作、本地数据存储等常用功能。Foundation.h 就像 C 语言中的 stdio.h,一般都需要引入

  • NSLog() 是 OC 中的格式化输出函数,相当于 C 语言中的 printf() 的升级版,不仅可以用来输出 C 语言中的数据,还可以输出 OC 中的数据。

#import <Foundation/Foundation.h>

int main() {
    NSLog(@"Hello, World!");
    int a = 100;
    float b = 3.14;
    char *str = "hello, c";
    NSString *NSstr = @"hello,object-c";
    NSLog(@"\n a: %d\n b: %f\n str: %s\n OC str: %@",a, b, str, NSstr);
    return 0;
}
  • @ 符号没有实际含义,只是用来作为 OC 字符串的特有标志。在 OC 中,字符串前面都要加 @,如果不加,就变成了 C 语言中的字符串,就要使用字符指针或字符数组来定义

OC 中的数据类型和数据结构

因为 OC 是完全兼容 C 的,所以 C 中的数据类型都可以在 OC 中使用。

先来看看 C 中有什么数据类型

  • C 语言数据类型
    • 基本类型
      • 数值(int、long、float、double)
      • 字符串(char)
    • 构造类型
      • 数组
      • 结构体(struct)
      • 共用体(union)
      • 枚举(enum)
    • 指针类型
    • 空类型void

很明显 C 中的数据类型有些少,当我们需要用到哈希表这样的数据结构的时候,就需要我们自己手写一个,OC 明显考虑到这个麻烦,所以添加了很多便于使用的数据结构。

比如有 NSObject、NSString(NSMutableString)、NSArray(NSMutableArray)、NSDictionary(NSMutableDictionary)、NSSet(NSMutableSet)、NSAttributedString(NSMutableAttributedString) 这些数据结构,使开发效率能够提高。

这些数据结构是由 Cocoa Foundation 框架提供的集合类,这些集合类中只可以放入对象,不能放入基本类型的数据。所以 Cocoa 提供了包裹类

  • NSNumber 类来包装 int、long、char 等基本数据类型,使其可以放入集合类中。
  • NSValue 可以将结构体、枚举、指针这些复杂的数据类型转换为对象放入集合类中。
  • NSNull 可以将 nil 包裹之后放入集合类中。

提取包裹类中的值

使用下列的方法可以提取出 NSNumber 实例中的 NSInteger 的值

-(NSInteger) integerValue

需要注意的是:NSInteger 不是一个对象,而是基本数据类型的 typedef

OC 中的属性声明

一般来说,属性是指一个对象的属性或者特性(也就是变量和方法)

属性的声明有一些规律:

  • 自动生成访问方法:

    能够为声明的实例变量自动生成访问方法。既可以同时生成 getter 方法和 setter方法,也可以只生成 getter,也可以手动定义访问方法。

  • 自动生成实例变量:

    如果不存在同名的实例变量的话,在生成访问方法的同时,也会自动生成同名的实例变量。

  • 更简单的调用访问方法

    可以通过 . 操作符来访问调用方法。

@property 的几种常用修饰词

nonatomic 和 atomic

nonatomic:非原子性,涉及到多线程的相关知识。访问方法被 nonatomic 修饰的情况下,意味着它执行过程中可以被打断,如果多个线程同时调用 getter 或者 setter 方法,那么就会出现值丢失或内存泄漏等错误

atomic (默认):原子性。和 nonatomic 正好相反,它对属性的访问进行了限制,保护了声明属性的安全,缺点就是:访问效率低,速度慢。

assign、copy、retain、unsafe_unretained、strong、weak

assign:单纯赋值,可用于基础数据类型和对象类型

copy:复制对象,使用对象的副本进行赋值

retain:进行保持操作

release:进行释放操作

unsafe_unretained:同 assign 一样

strong:强引用,同 retain 一样,用于 ARC

weak:弱引用,用于 ARC

readonly和readwrite

readwrite(默认):它代表这个属性即可以读,也可以写(可以调用它的 get 和 set 方法)

readonly:和 readwrite 不同,它代表这个属性只能读,不能进行写操作(只能调用 get 方法,不能调用 set 方法)

赋值时的选项

OC 中类和对象

OC 中的类和 C 中的结构体功能类似,但是 C 只能在结构体里面定义不同类型的变量,而 OC 可以在类里面定义变量和方法,和 C++ 里面的类相似。

首先来看一下 C 中的结构体

#include <stdio.h>

struct Student {
    char *name;
    int age;
    float score;
};

void display(struct Student stu){
    printf("%s的年龄是:%d,成绩是:%f\n", stu.name, stu.age, stu.score);
}

int main(int argc, const char * argv[]) {
    struct Student stu;
    stu.name = "beyhuang";
    stu.age = 22;
    stu.score = 88;
    display(stu);
    return 0;
}

再来看看 OC 中的类

#import <Foundation/Foundation.h>

//声明类Student
@interface Student : NSObject  //通过@interface关键字来声明类
//类所包含的变量
@property NSString *name;
@property int age;
@property double score;
//类所包含的函数
-(void)display;
@end  //使用@end关键字结束类的声明

//实现在类中声明的函数
@implementation Student  //通过@implementation关键字来实现类中的函数
-(void)display{
    NSLog(@"%@的年龄是 %d,成绩是 %f", self.name, self.age, self.score);
}
@end  //使用@end关键字结束类中函数的实现

int main(int argc, const char * argv[]) {
    //通过类来定义变量stu1,即创建对象stu1
    Student *stu1 = [[Student alloc] init];  //alloc函数为对象分配内存空间,init函数会初始化对象
    //操作类的成员
    stu1.name = @"beyhuang";
    stu1.age = 18;
    stu1.score = 66.66666;
    //调用类的函数
    [stu1 display];

    return 0;
}
  • OC 使用 @interface 来声明一个类;Student 是类的名称;student 后面的 NSObject 表示当前类派生自 NSObject

  • 在 OC 中,类所包含的变量和函数都有特定的称呼,变量被称为属性(Property),函数被称为方法(Method),属性和方法统称为类的成员(Member)。从上面的代码可以看出,声明类的属性要使用 @property 关键字,而声明类的方法不需要使用任何关键字。

  • - 号和+ 号代表的意思:

    • 减号表示

      为实例方法,必须使用类的实例才可以调用的。

      比如C语言中,一个方法的写法可能是:

      void hello(bool ishello)
      {
      ......
      }
    • 用Objective-C写出来就是

      -(void) hello:(BOOL)ishello
      {
      ......
      }
    • 加号表示类方法,这类方法是可以直接用类名来调用的,就是其他函数可以直接调用这个类中的这个函数,而不用创建这个类的实例。

  • 消息表达式

    • // [obj msg];
      [stu1 display];
      
    • 上面就是消息表达式的语法,其中消息接受者 obj 是一个对象,消息 msg 告诉它要去做什么

------------- 本文结束 感谢阅读 -------------