学习过Swift之后,好久没用已经生疏了,现在有项目来了,不得不停下手下的工作,开始学习OC,当然这篇文章会以Java基础和C基础作为支撑,这样学习起来入门很简单,可能这篇文章有点个人主义,用作个人笔记吧
基本数据类型:数值型(整型、浮点型),字符型(char)、布尔型(BOOL)、空类型(Void)、Block类型、指针数据类型(class、id类型)、特殊类型(SEL、nil)
1、instancetype和id类型
instancetype可以作为返回类型,可以返回和方法所在类相同类型的对象,只能作为返回值id可以作为返回类型,返回任意类型的objcetive-c的对象类型,既可以作为返回值也可以作为参数1、 类的声明语法
@interface Person : NSObject{ 属性声明 } 方法声明 @end特点:
@interface:相当于Java中的class类名后面的冒号:相当于Java中的extends2、类的实现语法
@implementation XYZPerson 方法实现{ } @end3、完整例子
4、创建对象
//第一种创建方式:创建一个可用的对象 Person *p=[Person new]; //new方法的内部会分别调用两个方法来完成2件事情 //1、使用alloc方法来分配存储空间(返回分配的对象) //2、使用init方法来对对象进行初始化 //1、调用类方法+alloc分配存储空间,返回未经初始化的对象 Person *p1=[person alloc]; //2、调用对象方法-init进行初始化,返回对象本身 Person *p2=[p1 init]; //第二种创建方式:以上2步简化为 Person *p=[[Person alloc] init]; //默认初始化完毕后,所有成员变量的值都为0 //用完对象要释放内存 [lisi release];究竟new方式和alloc/init方式有什么区别?
new和alloc/init在功能上是一致的,分配内存并完成初始化采用new方式只能采用默认的init方法完成初始化采用alloc的方式可以用自定义的构造方法完成初始化5、访问对象属性
//调用类的属性,语法:对象->属性名 lisi->age; lisi->name; //或者:(*对象名).对象属性 (*lisi).name6、调用方法
//调用无参方法,语法:[对象名 方法名] [Person eat] [Person run] //调用有参方法,语法:[对象名 方法名:参数] [Person eat:@"吃虾"] [Person run:5]7、@property和@synthesize
在头文件中声明属性
//编译器会自动补出其set和get方法 @property int age;在m文件中实现
//编译器会自动生成set和get方法的实现,默认已经自动@synthesize属性的值 @synthesize age;1、默认的构造方法
- (instancetype)init{ if(slef = [super init]){ //初始化 } return self; }2、自定义构造方法
一般构造方法都以init开头,这样并不是复写系统默认的构造方法,而是再添加一个构造方法
- (instancetype)initWithDict:(NSDictionary *)dict{ if(slef = [super init]){ //初始化并赋值 self.name = dict[@"name"]; } return self; }1、减号表示对象方法,语法:-(返回值类型)方法名:(参数类型)参数名
@interface Person : NSObject -(Void) someMethod; -(Void) someMethodWithValue:(someType)Value; @end特点:
函数的返回类型和参数类型必须用括号函数的形参用冒号表示2、加号表示静态方法(类方法),语法:+(返回值类型)方法名:(参数类型)参数名
@interface NSString: NSObject +(id) string; +(id) stringWithString:(NSString *)astring; +(id) stringWithFormat:(NSString *)format,...; @end区别:
对象方法可以直接访问属性,静态方法不能访问属性静态方法可用类名直接调用方法,而对象方法不行声明对象并提供get和set方法
#import <Foundation/Foundation.h> @interface Person : NSObject{ int _age; } - (void)setAge:(int)age; - (int)age; @end实现对象
#import "Person.h" @implementation Person - (void)setAge:(int)age{ //set方法 _age = age; } - (int)age{ //get方法 return _age; } @end点语法的使用
#import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]){ @autoreleasepool { Person *person = [[Person alloc] init]; person.age = 10;//点语法,等效与[person setAge:10]; //这里并不是给person的属性赋值,而是调用person的setAge方法 int age = person.age;//等效与int age = [person age]; //这里调用person的set方法 NSLog(@"age is %i", age); [person release]; } return 0; }为什么有些使用_age,有些语法使用self.age?
属性值:_age 点语法:self.age
下划线是一种编程规范,_age是直接拿到age这个属性,不通过getAge方法获取,建议在init里面使用_ageself.age相当于调用[self getAge],系统自动生成的代码(_age = age),其实也是_age,如果你重写了getAge方法,返回的值就不一样了1、OC与Java或C的区别
OC中的静态变量:它是私有的全局变量,不能直接通过类名访问,它只作用于它声明所在的.m文件中C或者Java中的静态变量:可以直接通过类名拿到这个变量,在其他类中可以进行修改2、静态变量全局化
不是说OC中静态变量不能使用在其他类中,可以通过静态方法向外提供该静态变量
在h文件中定义静态变量和向外提供静态变量的方法
#import <UIKit/UIKit.h> //静态变量 static int selectIndex; @interface TBC_SendPassword : UITabBarController //提供静态变量 +(int)getSelectIndex; @end在m文件中覆写该方法,提供静态变量,你可以在m文件中修改对应的selectIndex的值
+(int)getSelectIndex{ return selectIndex; }在其他类中需要使用该类的静态变量,首先在h文件中导入头文件
#import "TBC_SendPassword.h"在m文件中直接通过静态的方法的使用,获取对应的值
if([TBC_SendPassword getSelectIndex] != 0){ return; }相当于Java的main方法
#import <Foundation/Foundation.h> int main(int argc, const char * argv[]){ @autoreleasepool{ NSLog(@"Hello World"); } return 0; }特点:
Foundation.h是Foundation框架中的头文件,是OC一个基础类库,基本所有OC代码都要引入这个类库@autoreleasepool是OC的关键字,作用是对在关键字后面的程序自动进行内存回收特点:
导入系统类库用<>,导入自定义类库用””BOOL类型,包含两个值YES和NO,其实布尔类型就是整数1和0注意不能用C语言打印OC字符串,也不能用OC语言打印C字符串
NSMutableArray是长度可变数组,也就是说当数组前面的元素被删除后,后面的元素会往前移,而NSArray是长度不可变数组
//创建NSMutableArray NSMutableArray *mArray = [NSMutableArray array]; //添加元素 [mArray addObject:@"name"]; //移除元素 [mArray removeObject:@"name"]; //移除所有元素 [mArray removeAllObjects]; //取出元素 mArray[2];NSBundle是一个目录,其中包含了程序会使用到的资源,相当于项目中的主目录文件夹,NSBundle用得最多的是获取Plist文件,并获取Plist的内容,Plist文件可以简单理解为小数据库类型的文件,它在项目初始化时默认会创建一个info.plist文件,里面会存储系统的默认配置信息
//打印沙盒路径 NSLog(NSHomeDirectory()); //创建NSBundle NSBundle *bundle = [NSBundle mainBundle]; //获取NSBundle里myPic.png文件的路径的两种方法 NSString *path = [mainBundle pathForResource:@"myPic" ofType:@".png"]; NSString *path = [mainBundle pathForResource:@"myPic.png" ofType:nil]; //获取NSBundle里的Plist文件 NSString *plistPath = [mainBundle pathForResource:@"myList.plist" ofType:nil]; //通过Plist路径获取字典 NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:plistPath]; //通过Plist路径获取数组 NSArray *array = [NSArray arrayWithContentsOfFile:plistPath];OC中的KVC操作就和Java中使用反射机制去访问类中private权限的变量一样
1、kvc与对象
1.单个对象赋值:通过kvc的方式,可以省去自动解包和装包操作
//通过kvc方式设置属性 Person *p = [[Person alloc] init]; [p setValue:@"jiangwei" forKey:@"name"]; [p setValue:@22 forKey:@"age"]; //通过kvc方式读取属性 NSString *name = [p valueForKey:@"name"];2.单个对象对对象赋值:对象中包含另一个对象
Book *book = [[Book alloc] init]; Author *author = [[Author alloc] init]; //通过kvc方式设置对象 [book setValue:author forKey:@"author"];3.单个对象对数组赋值:对象中存在数组属性,数组装的是另一个对象
//author中的issueBook字段是个NSArray //通过kvc方式获取数组的大小,语法:NSArray.@count NSNumber *count = [author valueForKeyPath:@"issueBook.@count"]; //通过kvc方式获取书籍价格的总和,语法:NSArray.@sum+字段名 NSNumber *sum = [author valueForKeyPath:@"issueBook.@sum.price"]; //通过kvc方式获取书籍的平均值,语法:NSArray.@avg+字段名 NSNumber *avg = [author valueForKeyPath:@"issueBook.@avg.price"]; //通过kvc方式获取书籍的价格最大值和最小值,语法:NSArray.@max+字段名 NSNumber *max = [author valueForKeyPath:@"issueBook.@max.price"]; NSNumber *min = [author valueForKeyPath:@"issueBook.@min.price"];2、kvc与字典
1.通过获取字典字段,将字典转换为属性
self.name = dict[@"name"]; self.icon = dict[@"icon"];2.通过kvc方式进行赋值,自动将字段与属性匹配,前提是字段名和字典名必须相同
[self setValuesForKeysWithDictionary:dict];