OC基础语法

来源:互联网 发布:java orm 编辑:程序博客网 时间:2024/05/18 00:45

本人今年大四,大学专业是软件学院数字媒体技术,由于对游戏编程不感兴趣,不想从事Unity3D客户端游戏或者cocos2dx手机游戏,于是转行自学了几个月的iOS,从事手机客户端APP软件的开发,成功找到了一份待遇不错的实习,实习了两个月【还在实习中】,想着是时候该总结一下了,同时让自己更好的扎实基础。欢迎志同道合的大小伙伴们一起探讨与交流,逐步更新中。

大体是这个框架: Objective_C【基础语法、内存管理、多线程】

iOS【常用控件、界面布局、手势、推送、LBS】

网络通信【Http请求、JSON解析、XML解析、Socket】

数据持久化【属性列表、对象归档、SQLite、CoreData】

函数响应式编程【ReactiveCocoa】

设计模式【Delegate、KVO、KVC、Sigleton、Block】

应用结构【MVC、MVVM】

签名打包【各种证书、打包发布】

#import <Foundation/Foundation.h>int main(int argc, const char * argv[]) {    @autoreleasepool {        NSLog(@"Hello, World!");    }    return 0;}
1.在讲OC语法基础之前首先我们来理解一下编译过程【编译过程是计算机将敲入的代码转换成可以真正执行的指令的过程,计算机实际只能执行机器语言编写的指令】

1.1编码:程序员在编译前都需要将计算机指令敲入到一个文本编辑器中,称为编码。

很多编程语言都包含接口和实现的概念,OC分离接口和实现,使用两个不同的文本文件单独表示接口和实现【.m实现文件、.h接口文件】

1.2源码、编译代码和可执行文件

编译源码:第一步称为预编译【计算机为编译代码所进行的准备,在这一步,编译器会移除一些注释等不会变为可执行程序的代码,同时也会展开部分代码并重新排列某些指令,使得编译的第二部更高效】

第二步就是编译器将源代码真正转变成目标文件【目标文件的扩展名为.o,目标文件通常会存储在编译目录中,在上次编译后的源码文件没有改变的情况下,编译器就会跳过该源码文件的编译并复用上次编译产生的目标文件】

编译的最后一步称作链接【链接就是将上一步生成的目标文件连接起来以形成可执行的程序。除了目标文件外,库和框架也会被链接到可执行程序中。链接过程的结果就是实际的应用可执行文件】

1.3应用包:链接的结果就是一个可以在命令行运行的二进制文件。而在桌面应用中,结果通常是一个应用包,也就是硬盘上的一个包含可执行程序和图片、声音等运行应用所需资源的目录。【应用包只不过是硬盘上包含一组文件的目录】

2.结构体

struct Test {    float x;    float y;};typedef struct{    float x;    float y;} TestXY;int main(int argc, const char * argv[]) {    @autoreleasepool {          struct Test P;        P.x = 20;        P.y = 30;         TestXY PP;        PP.x = 50;        PP.y = 60;    }    return 0;}
2.1结构体由struct表示,是一种可以包含多个子变量的自定义类型【先定义Test这个结构体,再申明P这个结构体实例,然后进行赋值操作】

2.2每次想定义一个Test的时候,都需要输入struct Test,这非常的繁琐,可以使用typedef【类型定义】解决。

3.枚举

typedef enum{    ORDER_UNPAY = 0,    ORDER_UNSHIPPED = 1,    ORDER_SHIPPED = 2,    ORDER_RECEIVED = 3,    ORDER_FINISHED = 4,    ORDER_SALEWAITPROCESS = 5,    ORDER_SALEPROCESSING = 6,    ORDER_CLOSE = 7,}EnumOrder;

typedef NS_ENUM(NSInteger, EnumOrder) {    ORDER_UNPAY = 0,    ORDER_UNSHIPPED = 1,    ORDER_SHIPPED = 2,    ORDER_RECEIVED = 3,    ORDER_FINISHED = 4,    ORDER_SALEWAITPROCESS = 5,    ORDER_SALEPROCESSING = 6,    ORDER_CLOSE = 7,};
3.1推荐使用上面的第二种结构体定义

4.面向对象三大特性

4.1封装:屏蔽内部实现的细节,仅仅对外提供接口。【成员变量一般不会对外直接暴露,保证数据安全性】

4.2继承:子类获得父类的特性。【提高代码复用性,但耦合性太强】

4.3多态:某一类事务的多种形态,多态是指从一个给定类创建的任何对象都可以被该对象的使用者视为是该类的实例,或者是该类的父类的实例。【提高了代码的扩展性】

多态产生的条件是:1)有继承关系。2)子类重写父类的方法。3)父类指针指向子类的对象。【如果父类指针指向子类对象,需要调用子类特有的方法,必须先强制转换为子类才可以调用】


5.@property编译器指令

5.1利用@property可以自动生成setter/getter方法的声明和实现,同时系统会自动生成一个以_开头的成员变量。

5.2如果需要对传入的数据进行过滤,则需要重写getter/setter方法。

5.3@property修饰符

readonly 只读属性【只能使用getter方法】

readwrite 可读可写属性

assign 【会对对象直接赋值,而不会进行retain操作,只可以对基本数据类型等使用】

retain  对指针的拷贝【表示对NSObject及其子类对象release旧值,再retain新值,是对象的应用计数加1】

atomic 对对象的操作属于原子操作,主要是在多线程的环境下,提供多线程访问的安全。【如果不涉及到多线程,不建议使用,因为atomic比nonatomic更耗费系统资源】

nonatomic 非原子性访问,不加同步,多线程并发访问会提高性能

copy  对内容的拷贝【重新建立一个新的计数为1的对象,然后释放旧的值】

strong 强引用,类似于retain

weak 弱引用,类似于assign

【基本类型用assign,NSString用copy或者strong,对象用strong,避免循环引用则用copy】


6.数据类型

6.1静态数据类型:在编译时就知道变量的类型【例如:NSObject *】

6.2动态数据类型:在编译的时候,编译器并不知道变量的真实类型,只有在运行的时候才知道它的真实类型【例如:id】

6.3instancetype和id的区别:

1)id在编译的时候不能判断对象的真实类型,instancetype在编译的时候可以判断对象的真实类型。

2)id可以用来定义变量,可以作为返回值、形参,instancetype只能作为返回值。

3)如果init方法的返回值是instancetype,那么将返回值赋值给其他对象会报警告,id则不会。

4)建议自定义构造方法,返回值尽量使用Instancetype,不要使用id。


7.字符串、数组、字典的使用

7.1字符串简单总结

#import <Foundation/Foundation.h>int main(int argc, const char * argv[]) {    @autoreleasepool {                NSString *str1 = @"hello";        NSString *str2 = @"helloWorld";        NSString *str3 = @"123";        BOOL flag = 0;                //比较两个字符串的内容是否相同        flag = [str1 isEqualToString:str2];        NSLog(@"两个字符串的内容是否相同:%i", flag);                //比较两个字符串的地址是否相同        flag = (str1 == str2);        NSLog(@"str1地址是%p", str1);        NSLog(@"str2地址是%p", str2);        NSLog(@"两个字符串的地址是否相同:%i", flag);                //比较两个字符串的大小        long newFlag = [str1 compare:str2];        NSLog(@"%ld", [str1 length]);//求字符串的长度        NSLog(@"%ld", [str2 length]);        NSLog(@"两个字符串的大小是否相同:%ld", newFlag);                NSLog(@"%c",[str1 characterAtIndex:1]);//截取第几个字符                int a = [str3 intValue];//将字符串转化为整形数据        NSLog(@"%i", a);                NSRange range = [str2 rangeOfString:@"oW"];//查找子串【找不到返回NSNotFound,找到返回位置和长度】        if (range.location != NSNotFound) {            NSLog(@"%ld %ld", range.location, range.length);        }                BOOL flag1 = [str2 hasPrefix:@"he"];//判断字符串是否以指定字符串开头        BOOL flag2 = [str2 hasSuffix:@"uu"];//判断字符串是否以指定字符串结尾        NSLog(@"字符串是否以he开头:%i", flag1);        NSLog(@"字符串是否以uu结尾:%i", flag2);                //拼接字符串        NSString *string1 = [str1 stringByAppendingString:str2];        NSLog(@"%@", string1);            }    return 0;}

7.2数组简单总结

#import <Foundation/Foundation.h>int main(int argc, const char * argv[]) {    @autoreleasepool {                //NSArray只能存放任意的OC对象,不能存储非OC对象        //NSArray是不可变的,一旦初始化完毕后,它里面的内容就永远是固定的,不能删除里面的元素,也不能再往里面添加元素                //初始化数组        NSArray *arr1 = [NSArray arrayWithObjects:@"hello", @"world", @"good", @"morning", nil];        NSArray *arr2 = @[@"good", @"morning", @"hello", @"world"];                NSLog(@"%@", [arr1 objectAtIndex:0]);//取出数组的某个元素        NSLog(@"%@", arr2[0]);                //遍历NASrray数组        for (NSString *obj in arr1) {            NSLog(@"obj = %@", obj);        }                //对数组进行排序【元素不能是自定义对象】        NSArray *arr3 = [NSArray arrayWithObjects:@(1), @(34), @(56), @(13), @(7), nil];        NSArray *newArr2 = [arr3 sortedArrayUsingSelector:@selector(compare:)];        NSLog(@"排序之后的数组是:%@", newArr2);//输出的格式带有小括号                //将数组写入文件中        BOOL isSuccess = [arr2 writeToFile:@"/Users/coolzhen/Desktop/arr2.plist" atomically:YES];        NSLog(@"isSuccess = %i", isSuccess);                //从文件中读取一个数组        NSArray *arr4 = [NSArray arrayWithContentsOfFile:@"/Users/coolzhen/Desktop/arr2.plist"];        NSLog(@"%@", arr4);                //*****************************可变数组*****************************//                //不能通过@[]来创建一个可变数组,因为@[]创建出来的是不可变数组        NSMutableArray *arr11 = [[NSMutableArray alloc] init];        NSMutableArray *arr12 = [NSMutableArray array];                //给可变数组增加内容        [arr11 addObject:@"hello"];        [arr12 addObjectsFromArray:@[@"hello", @"world", @"good", @"afternoon"]];        NSLog(@"%@", arr11);        NSLog(@"%@", arr12);            }    return 0;}

将数组写入文件中的效果图如下:


7.3 字典的简单总结

#import <Foundation/Foundation.h>int main(int argc, const char * argv[]) {    @autoreleasepool {                //创建字典【字典里一个Key对应一个value,存储的都是键值对】        NSDictionary *dict1 = [NSDictionary dictionaryWithObject:@"dog" forKey:@"name"];        NSDictionary *dict2 = [NSDictionary dictionaryWithObjects:@[@"cat",@"21"] forKeys:@[@"name", @"age"]];        NSDictionary *dict3 = @{@"name":@"fish", @"age":@"32"};//简写                NSString *name = [dict1 objectForKey:@"name"];//取出字典的某个值        NSLog(@"dict1的名字是%@",name);        NSLog(@"dict2的名字是%@, 年龄是%@", [dict2 objectForKey:@"name"], [dict2 objectForKey:@"age"]);        NSLog(@"dict3的名字是%@, 年龄是%@", dict3[@"name"], dict3[@"age"]);        NSLog(@"dict3的个数:%lu", [dict3 count]);//获取字典的个数                //遍历字典第一种方法        for (int i = 0; i < dict3.count; i++) {            NSArray *keys = [dict3 allKeys];            NSString *key = keys[i];            NSString *value = dict3[key];            NSLog(@"key = %@, value = %@", key, value);        }                //遍历字典第二种方法        for (NSString *key in dict2) {            NSString *value = dict2[key];            NSLog(@"key = %@, value = %@", key, value);        }                //将字典数据写入文件之中        BOOL isSuccess = [dict2 writeToFile:@"/Users/coolzhen/Desktop/dict2.plist" atomically:YES];        NSLog(@"isSuccess = %i", isSuccess);                //从文件中读取字典数据        NSDictionary *newDict = [NSDictionary dictionaryWithContentsOfFile:@"/Users/coolzhen/Desktop/dict2.plist"];        NSLog(@"%@", newDict);//字典中保存的数据是无序的,和数组不一样    }    return 0;}
将字典写入文件中的效果图如下:



1 0
原创粉丝点击