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
文件区分
// 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;
// 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
#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++比较相似
@private
int _age;
@public
NSString *_name;
public:
int a;
private:
int b;
不同的是,OC中的方法是没有修饰符的概念的,默认均为public访问,这跟其他面向对象语言略有差异。实现私有方法的方法是:在.m
文件中实现该方法,却不在.h
文件中声明该方法(比如上面例子中的nothing
方法)。
继承
OC是单继承,通过super
关键字指向父类,该关键字的含义是变化的,指向当前的调用者
// student.h
#import "Person.h"
@interface Student : Person
{
int _grade;
}
- (int) grade;
- (void) setGrade:intgrade;
// 覆盖父类方法
- (void)introduceSelf;
@end
// 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
// 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++要简单很多。
Person *p5;
// p5 = [[Person alloc] init];
p5 = [[Student alloc] init];
[p5 setName:@"Txm"];
[p5 introduceSelf]; // 根据对象具体的类型调用其方法
小结
尽管OC的写法跟之前学习的其他语言有比较大的出入(C++我忘得一干二净了),但是我觉得:面向对象的特性与语言无关,抛开语言特性,大部分东西都是相同的,因此不必过于拘泥于语法。
不要忘记初衷啊~我只是想试试IOS的webview,学iOS开发真的不是我的本意...
你要请我喝一杯奶茶?
版权声明:自由转载-非商用-保持署名和原文链接。
本站文章均为本人原创,参考文章我都会在文中进行声明,也请您转载时附上署名。