1.如何理解OC
C语言是一种面向过程的语言,OC则是面相对象的语言,所以想要理解OC就要先了解面向过程和面向对象。
面向过程是以事件为中心,关注的是完成事件的详细步骤,一步一步如何实现。
面向对象是以事务为中心,关注的是每个事物具有的行为和特征,而完成该事件只是事物所有功能中的几个小功能而已。而在OC中具有相同特征和行为的事物叫类,类的实例就是对象(对象相当于变量)。
2.OC中的.h和.m文件
OC中的.h文件是类的接口部分,从@interface开始 类名 + 父类名 到@end结束
而.m文件是类的实现部分,从@implementation开始 Teacher类名(要对哪个类进行实现) 一直到@end结束
在.h和.m中会存在实例变量和方法,写在.h中其它类引用头文件后可以使用,写在.m中只有本类可以使用,并且.h文件中的方法必须在.m文件中实现。
实例变量 -- 类的特征 -- 等同于结构体成员,必须写在大括号之内,方法 -- 类的行为 -- 相当于C语言的函数。
方法是由方法名 - 参数名 - 参数类型三部分组成,有 -号方法 和 +号方法
-号方法: 对象方法 调用是[对象名 方法名]
+号方法: 类方法 调用是 [类名 方法名]
实例变量存在可见度问题
@public:公开的,可以在本类和子类中直接访问,可以在其它文件中通过对象->实例变量访问。
@protected:受保护的,可以在本类和子类中直接访问,其它文件不可访问,默认可见度。
@private:私有的,只可以在本类中直接访问
@package:这个是系统一些文件来使用
3.继承和初始化
继承的优势:可以节省代码,增强程序的可扩展性和可修改性。
1.继承的上层:父类 , 继承的下层:子类
2.继承具有单向性:只有单向传递,如果A作为B的父类,则A就不能再成为B的子类。
3.继承具有传递性:C继承于B,B继承于A,那么C具有A和B的所有内容。
4.子类继承父类的全部实例变量和方法。
5.子类从父类继承过来的内容就是自己的,只不过来源于父类。
原则:当多个类中出现部分相同的特征和行为时,可以将相同部分写成一个父类,其它类继承即可。
当子类继承父类后,对于父类的方法一般有三种使用方法
1.原来东西不动 直接用
2.引用后再进行自己的修改
3.只用名,所有东西不用,全重写
修改或重写要使用[super 方法名]
super不是对象,它是系统编译器的命令,作用是告诉系统我要执行原来的父类方法。
为单一实例变量赋值的方法叫setter方法(设置器)
获取单一实例变量的值的方法叫getter方法(访问器)
setter方法:-号方法,无返回值,set开头 + 对应实例变量的名字(首字母大写)有且只有一个参数,参数的类型和实例变量的类型相同,参数名和实例变量的名相同
例如:- (void)setName:(NSString *)name;
getter方法:- 号方法,有返回值,返回值类型和实例变量类型相同,方法名 get + 实例变量名(首字母大写),无参数
例如:- (NSString *)getName;
instancetype id 返回的是任意类型
自定义初始化方法的声明 -号方法
- (instancetype)initWith方法名:(参数类型)参数名
例如:- (instancetype)initWithName:(NSString *)name; .h
- (instancetype)initWithName:(NSString *)name{
self = [super init];
if (self) {
_name = name; }
return self; } .m
便利构造器 +号方法 调用类方法,因为调用的是类方法,没有进行分配空间初始化,所以在内部把对象进行初始化,返回对象。
+ (类名 *) (init用小写类名代替)With方法名:(参数类型)参数名
例如:+ (Person*)personWithName:(NSString *)name; .h
+ (Person*)personWithName:(NSString *)name{
Person *per = [[Person alloc] initWithName:name];
return per; } .m
4.属性
属性:OC2.0版本定义的语法,提供了setter,和getter方法的默认实现,在一定程度上提高了我们的代码效率,并且提高程序的安全性。
属性的声明:在.h中使用@property声明属性:
@property(readonly)NSString *name;
@property(readwrite, nonatomic, copy)NSString *name;
在.h中声明了setter和getter方法。
读写性控制:
readonly:只读状态,告诉编译器,属性只生成getter方法,不生成setter方法。
readwrite:读写状态,告诉编译器,我们既生成setter方法也生成getter方法,就是设置器和访问器都生成。(默认的读写性)
原子性:
atomic:原子性,setter和getter方法在多线程下是完全安全的,既在setter和getter方法内对多线程的访问进行了处理,但是它的效率非常的低(默认的原子特性).
nonatomic:非原子性,setter和getter方法中内部不会对多线程的访问进行处理,既这个setter和getter方法中只实现我们最基本的setter和getter方法。(pass: 这是我们最常用的原子特性)
语义设置:
如果我们定义的属性类型是基本类型:(int ,float ,char ,NSInteger)我们都使用的语义设置是 assign
如果我们定义的属性类型是对象类型:(Person *per)
字符串类型我们用的语义设置是 copy
其它类型我们用的语义设置是 retain
@synthesize 相当于实现了setter和getter方法
在Xcode4.6以后我们可以不写属性的实现了,系统自动会为我们生成属性的实现。
属性的作用:声明和实现setter和getter方法,如果方法内部操作的实例变量未定义,那么系统就会自动生成一个 _属性名 的实例变量,但是生成的实例变量的可见度是私有的,子类不能访问。
例:
.h @property(nonatomic, copy)NSString *name;
@property(nonatomic, assign)NSInteger score;
- (void)setAge:(NSInteger)age;
- (NSInteger)age;
.m
- (void)setAge:(NSInteger)age { _age = age; }
- (NSInteger)age { return _age; }
5.字符串:NSString
字符串分为不可变字符串(NSString) 和 可变字符串(NSMutableString)
一.字符串的创建方式
第一种方式: char a[] = "abc";
NSString *string1 = [[NSString alloc] initWithUTF8String:a]; // 也可以使用便利构造器创建
******initWithUTF8String:将C语言中的字符串转换为oc中的字符串******
第二种方式: 字面量(最常用的字符串创建方式)
NSString *string2 = @"abc";
第三种方式:(建议使用这种方式或字面量方式)
NSString *string3 = [[NSString alloc] initWithFormat:@"hello abc"];
****** initWithFormat: ********
作用1:创建一个普通的字符串对象。
作用2:将别的类型的对象转换成字符串类型的对象。
作用3:字符串拼接
二.使用字符串
1.字符串长度
NSString *string = [NSString stringWithFormat:@"abcdefg"];
NSUInteger length = string.length; // 无符号长整型长度
NSLog(@"%lu", length); // 打印无符号长整型用lu
2.获取字符串中的字符
NSString *string = [NSString stringWithFormat:@"abc哈哈"];
unichar c = [string characterAtIndex:2]; //unichar 实质上表示 unsigned short 无符号短整型
// 字母
NSLog(@"%c", c);
// 汉字
unichar D = [string characterAtIndex:9];
NSLog(@"%C", D);
3.判断字符串是否相等
NSString *string1 = @"heihei";
NSString *string2 = @"haha";
if ([string1 isEqualToString:string2]) {
NSLog(@"两个字符串相等");
}else{
NSLog(@"两个字符串不相等");
}
****直接进行比较其实是判断的字符串地址是否相同*****
if (string1 == string2) {
NSLog(@"地址相等");
}else{
NSLog(@"地址不相同");
}
4.获取子字符串
NSString *string = @"abcdefg";
截取下标为5之前的字符。(不包含5)
NSString *string1 = [string substringToIndex:5];
截取下标为5之后的字符(包含5)
NSString *string2 = [string substringFromIndex:5];
截取从下表3开始长度为4的字符串
NSString *string3 = [string substringWithRange:NSMakeRange(3, 4)];
5.字符串拼接
NSString *string = @"ab";
NSString *string2 = [string stringByAppendingString:@"cd"];
NSString *string3 = [string2 stringByAppendingFormat:@"%d", 1233];
6.字符串替换
NSString *string = @"autorelease";
NSString *string2 = [string stringByReplacingOccurrencesOfString:@"a" withString:@"b"];
// 从下标3开始2位的字符串替换成字符串heihei
NSString *string3 = [string stringByReplacingCharactersInRange:NSMakeRange(3,2) withString:@"heihei"];
7.大小写转换
NSString *string = @"abcdefg";
(1)全部大写
NSString *upperString = [string uppercaseString];
(2)全部小写
NSString *lowercaseString = [string lowercaseString];
(3)首字母大写
NSString *capitalStr = [string capitalizedString];
8.判断开头结尾
NSString *string = @"http://www.jianshu.com";
判断是否以http开头
BOOL isPrefix = [string hasPrefix:@"http"];
判断是否以com结尾
BOOL isSuffix = [string hasSuffix:@"com"];
9.字符串转换为其它类型 类型+Value
例:NSString *string1 = @"123"; 转换为长整型
NSInteger a = [string1 integerValue];
三.可变字符串
NSMutableString *mStr = [[NSMutableString alloc] initWithFormat:@"china"];
在china之后拼接上beijing 1转换为字符串类型
[mStr appendFormat:@"beijing %d", 1];
[mStr appendString:@"heihei"];
插入字符串
[mStr insertString:@"hahe" atIndex:0];
删除字符串
[mStr deleteCharactersInRange:NSMakeRange(4, 2)];
替换字符串
[mStr replaceCharactersInRange:NSMakeRange(4, 2) withString:@"123"];
重置字符串
[mStr setString:@"heihei"];