侧边栏

Objective-C基础入门

发布于 | 分类于 编程语言/Objective-C

最新需要适配iPhoneX相关的webiview页面,由于没有真机(九千大洋的手机简直了~),为了测试及检验适配效果,决定学习iOS开发并在模拟器上对页面进行适配。大概看了一下iOS的Demo代码,感觉Objective-C的语言风格有点魔幻,因此在这里稍作梳理。我只是抱着能在APP中运行webview的目的而已~

<!—more—>

发现一个很奇特的现象,与其他语言相比,网上关于OC基础教程居然很少~

开发环境

目前使用的是Xcode(Version 9.0.1 (9A1004))进行开发

  • 使用XCode集成开发环境,新建项目->Mac OS Application项目->Command Line项目即可
  • XCode设置字体时,可以command + A全选所有,然后统一设置字体,

感觉编译还是挺快的,跟写web刷新一下页面的速度差不多,不过没有livereload、热更新等插件,哈哈~

简单梳理

  • OC跟C++类似,均为C语言的扩展,尽管已经有30多年的历史了,但国内大多数人接触并学习OC是起源于2010年之后(iPhone发布)
  • @符号在OC中有特殊用法,编译器会找到他然后做特殊处理,比如区分C字符串和OC字符串
  • 声明变量及初始化与C语言十分相似, 相关运算符也基本通用,支持变量随用随声明
  • 基本数据类型,包括int,float,double,char
  • 限定词long,long long,short,sunsigned,signed
  • 分支运算与循环运算与C基本相似,OC居然支持goto!!!
  • 函数定义包括返回类型,函数名和形参类型,包括完整的函数签名,貌似函数不支持默认参数
  • NSLog输出变量使用NSLog(@"%@", varName)

面向对象

这里参考: iOS - OC 面向对象语法

PS:写OC代码的感觉就是不用按住Shift键来输入小括号了,这个感觉确实不错,虽然写其他语言的代码习惯了。

类的声明和实现

类的声明和实现是分开的,以.h文件和.m文件区分

objective-c
// person.h
@interface Person: NSObject{
  	// 成员变量
    @private
        int _age;
    @public
        NSString *_name;
}

// 方法声明

// 构造函数
- (id)initWithAgeAndName:intage name:(NSString *)name;

// 静态方法
+ (Person *)getInstance;

// setter和getter
- (int)age;
- (void)setAge: (int)age;

- (void)setName: (NSString *)name;

- (void)introduceSelf;
- (void)greet:(NSString *)name age:intage;
objective-c
// person.m
#import "Person.h"

@implementation Person: NSObject

// 方法实现,回忆起了重写一遍方法声明的恐惧吗
- (id)initWithAgeAndName:intage name:(NSString *)name{
    if(self = [super init]){
        _age = age;
        _name = name;
    }
    
    return self;
}

// 使用静态方法实现单例
static Person *person;
+ (Person *) getInstance{
    if (person == nil){
        person = [[Person alloc] init];
    }
    return person;
}

- (int) age {
    return _age;
}

- (int) age {
    return _age;
}

- (void)setAge:intage {
    _age = age;
} 

- (void)setName:(NSString *)name {
    _name = name;
}

- (void)greet:(NSString *)name age:intage {
    NSLog(@"Hello %@, you are %d years old",name, age);
}

// 这里没有在类中声明该方法,也可以通过编译
- (void)nothing{
    NSLog(@"Nothing");
}

- (void)introduceSelf {
    NSLog(@"My name is %@", _name);
  	// 通过self关键字访问当前对象
    [self nothing];
}

@end
objective-c
#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p1 = [[Person alloc] init]; // init 是NSObject的默认构造函数
        
      	// 方法调用
        [p1 setAge:10];
        int age = [p1 age];
      
        // int age = p1.age; // 与[p1 age]等价
        NSLog(@"%d", age);
      
      	NSString *str = [[NSString alloc] initWithFormat:@"%@",@"Txm"];
        [p1 greet: str age:24];
        [p1 setName:str];
      	// 使用公共属性
        NSLog(@"%@", p1->_name);
      	
      	// 使用构造函数
      	Person *p2 = [[Person alloc] initWithAgeAndName:24 name:@"Txm"];
        [p2 introduceSelf];
      	
      	// 以类名直接调用静态方法
      	Person *p3 = [Person getInstance];
        Person *p4 = [Person getInstance];
        
        NSLog(@"%@", p3 == p4 ? @"same" : @"different");
    }
    return 0;
}

可以发现类的定义和实现与C++比较相似,除了写法略有区别之外。而实例化对象和方法调用就有很大的差别了

  • 减号方法,指普通对象方法声明;加号方法,指类的静态方法声明
  • OC中的点语法是Xcode的高级功能,它将点语法会自动转换成getter,setter方法,这意味着使用点方法必须有两个条件:
    • 必须是属性
    • 有对应的setter和getter

封装

访问权限也是通过protect,private,public来实现的,这里的做法和使用方式跟C++比较相似

objective-c
@private
	int _age;
@public
	NSString *_name;
c++
public:
	int a;
private:
	int b;

不同的是,OC中的方法是没有修饰符的概念的,默认均为public访问,这跟其他面向对象语言略有差异。实现私有方法的方法是:在.m文件中实现该方法,却不在.h文件中声明该方法(比如上面例子中的nothing方法)。

继承

OC是单继承,通过super关键字指向父类,该关键字的含义是变化的,指向当前的调用者

objective-c
// student.h
#import "Person.h"

@interface Student : Person
{
    int _grade;
}
- (int) grade;
- (void) setGrade:intgrade;

// 覆盖父类方法
- (void)introduceSelf;
@end
objective-c
// Student.m
#import "Student.h"

@implementation Student

- (int) grade{
    return _grade;
}

- (void) setGrade:int grade{
    _grade = grade;
}

- (void)introduceSelf {
  	// super关键字调用父类,父类方法中的self不受影响
    [super introduceSelf];
    NSLog(@"I'm student");
}

@end
objective-c
// main.m
Student *st = [[Student alloc] init];
[st setGrade:100];
[st setName:@"Txm"];

NSLog(@"grade is %d", st.grade);

// 调用父方法
[st greet:@"Txm" age:24];
// 覆盖父类方法并调用
[st introduceSelf];

多态

多态是一个非常重要的特性。OC中的多态比C++要简单很多。

objective-c
Person *p5;
// p5 = [[Person alloc] init]; 
p5 = [[Student alloc] init];

[p5 setName:@"Txm"];
[p5 introduceSelf]; // 根据对象具体的类型调用其方法

小结

尽管OC的写法跟之前学习的其他语言有比较大的出入(C++我忘得一干二净了),但是我觉得:面向对象的特性与语言无关,抛开语言特性,大部分东西都是相同的,因此不必过于拘泥于语法。

不要忘记初衷啊~我只是想试试IOS的webview,学iOS开发真的不是我的本意...

你要请我喝一杯奶茶?

版权声明:自由转载-非商用-保持署名和原文链接。

本站文章均为本人原创,参考文章我都会在文中进行声明,也请您转载时附上署名。