Objective-C语言基础

Author Avatar
达令哥 5月 05, 2016

我学习IOS的一个记录笔记

面向对象的编程

OO:面向对象
OOA:分析
OOD:设计
OOP:实现
优点:易于维护和扩展
核心思想:封装,继承,多态
类:类是抽象的
对象:对象是类中的个体,成员
类和对象的关系:类是对象的抽象和封装;对象是类的实例化,个体化,具体化。
定义类:
方法:+表示静态方法 访问通过[类名 方法名]
-表示实例方法 访问通过[对象名 方法名]
无参数:方法的修饰 (返回类型) 方法名{}
有参数:方法的修饰 (返回类型) 方法名:(类型)名 :(类型)名。。。。{}

封装

封装:如果是@public违反了,面向对象的三大特征
方法定义时:-set首字母大写
-get首字母大写
简便方法: @property (readwrite) int cId; //相当于.h文件声明 readwrite 读写
@synthesize cId;//相当于.m文件定义
@property(assign,nonatomic) NSString * loginid;
内存计数器,线程安全管理
基本数据类型用 assign
对象类型用 strong

属性的属性
第一类:读写性控制(readonly、readwrite、setter、getter)
readonly,告诉编译器,只声明getter方法(无setter方法)。
例:@property(readonly)NSString * name;

第二类:原子性控制(nonatomic、atomic)
atomic:setter、getter方法在多线程访问下是绝对安全的,即setter、getter内部做了多线程访问处理。原子性控制的默认设置是 atomic。
noatomic:setter、getter方法内部不会做多线程访问处理,仅仅是普通的setter、getter方方法。

第三类:语义设置(assign[week]、retain[strong]、copy)
assign:setter、getter内部实现是直接赋值。基本数据类型不需要内存优化
retain:setter、getter的内部实现会做内存优化。 类类型需要内存优化

继承

1:解决代码冗余 【多个类有相同的代码】
2:易于维护和扩展
3:多态

多态

继承 协议

字符串

NSString:不可便字符串,即:创建以后,内容和长度不能更改。
NSMutableString,可变字符串,即:创建以后,内容还可以修改。
创建一个新的字符串,可以使用实例方法和便利构造器。
NSString使用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
NSString * tes:t =@"1234567";
NSLog(@"%lu",(unsigned long)[test length]);//字符串长度
NSLog(@"%c",[test characterAtIndex:1]);//根据索引得到单个字符
NSLog(@"%@",[test substringFromIndex:1]);//截取某个字符串从开始到结束
NSRange nr={1,3};//1 (索引位置) 3(截取的长度)
NSLog(@"%@",[test substringWithRange:nr]);//包含该索引的位置
NSString * result=[test substringWithRange:nr];
NSLog(@"%@",[result stringByAppendingString:@"dd"]);//添加新内容
if(test == nil || test.length){
//判断是否为空
}
if([test isEqualToString:result]){
//比较俩个字符串内容是否相同
}
int a = 10;
NSLog(@"%@",[NSString stringWithFormat:@"%d",a]);//基本数据类型转换字符串
NSLog(@"%i",[test intValue]);//字符串转基本数据类型
NSLog(@"%f",[test floatValue]);//字符串转浮点类型
NSLog(@"%@",[result uppercaseString]);//将字符串的字母转换成大写
NSLog(@"%@",[result lowercaseString]);//将字符串的字母转换成小写

NSMutableString使用方法:

1
2
3
NSMutableString * str = [NSMutableString stringWithString:@"有钱任性,没钱任命"]; //可变字符串创建
[str appendString:@"aaa"];//添加普通的字符串
[str appendFormat:@"我的名字:%@ 我的年龄:%d",@"ding",24];//添加字符串 整形

集合

数组的遍历:有三种

1
NSArray * na =[[NSArray alloc] initWithObjects:@"11",@"22",@"33", nil];

第一种是普通for

1
2
3
4
5
6
7
8
9
10
11
12
for (int i=0; i<[na count]; i++) {
NSLog(@"%@",[na objectAtIndex:i]);
}
NSMutableArray * nma = [[NSMutableArray alloc] init];
[nma addObject:@"abc"];
[nma addObject:@"cba"];
[nma insertObject:@"2" atIndex:1];
[nma removeObject:0];
[nma objectAtIndex:2];
NSNumber * nsn=[[NSNumber alloc] initWithInt:3];
nma addObject:nsn];

第二种增强for

1
2
3
for (NSObject *o in nma) {
NSLog(@"%@",o);
}

第三种迭代器(效率最高)

1
2
3
4
5
NSEnumerator * ne = [nma objectEnumerator];
id object;
while (object = [ne nextObject]) {
NSLog(@"数组中的对象:%@",object);
}

字典

字典类的特点:
与数组不同,字典靠key存取元素。
key不能重复,value必须是对象。
键值对在字典中是无序存储。
字典分:不可变字典(NSDictionary) 可变字典(NSMutableDictionary)
NSDictionary:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//初始化俩个元素
NSDictionary * nsd = [NSDictionary dictionaryWithObjectsAndKeys:
@"zhangsab",@"2",@"wangwu",@"1", nil];
//第一种方式:得到所有键的集合
//第一种遍历普通for
for (int i =0; i<[nsd count]; i++) {
NSObject * key = [nsd allKeys][i];
NSObject * value = [nsd objectForKey:key];
NSLog(@"i=%d key=%@ value=%@",i,key,value);
}
//第二中遍历增强for
for(NSObject * no in [nsd allKeys]){
NSObject * value = [nsd objectForKey:no];
NSLog(@"key=%@ value=%@",no,value);
}
//第三种遍历 迭代器最好
NSEnumerator * ne = [[nsd allKeys] objectEnumerator];
NSObject * object;
while (object = [ne nextObject]) {
NSLog(@"key=%@ value=%@",object,[nsd objectForKey:object]);
}
//第二种方式:得到所有值的集合
for(int i =0;i<[[nsd allValues] count];i++){
NSLog(@"%@",[nsd allValues][i]);
}

NSMutableDictionary:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//便利构造器,初始化有十个长度的字典,实际长度可变
NSMutableDictionary * nsmd = [NSMutableDictionary dictionaryWithCapacity:10];
[nsmd setObject:@"lishi" forKey:@"2"];//添加
[nsmd setObject:@"wanger" forKey:@"1"];
for(NSObject * no in [nsmd allKeys]){
NSObject * value = [nsmd objectForKey:no];
NSLog(@"key=%@ value=%@",no,value);
}
[nsmd removeObjectForKey:@"1"];//根据指定KEY删除
for(int i =0;i<[[nsmd allValues] count];i++){
NSLog(@"%@",[nsmd allValues][i]);
}
[nsmd removeAllObjects];//删除掉所有数据

块和字面量


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
__block int c=1;
int (^Sum)(int,int)=^(int a,int b){
c++;
return a+b+c;
};
NSLog(@"%i",Sum(10,11));
NSString *stopName =@"王五";
NSArray * array = @[@"张三",@"李四",@"王五",@"赵六",@"王二"];
/**
* 快方法遍历数组
*
* @param obj 对象
* @param idx 索引
* @param STOP 是否接受
*
* @return return value description
*/
[array enumerateObjectsUsingBlock:^(id obj,NSUInteger idx ,BOOL * STOP){
NSLog(@"第%d项内容是%@",(int)idx,obj);
if ([stopName isEqualToString:obj] || idx == pIndex) {
*STOP = YES;
}
}];

字面量:是一种简易表示值的方法;

点语法

在正常情况下:访问类中的成员
第一种是:->
第二种是:[]
不像其它语言:.不支持
当定义成属性之后,就可以使用.语法

类别

继承和类别的区别
类别:能添加方法、特征、不能添加属性
继承:能添加方法、特征、属性
类别添加的方法,是原始类的一部分
继承是新类[子类]添加了一个方法,父类什么都没有变化
类别跟原类没有区别
继承必须要使用子类,才能用其方法
好处:遵守了开闭原则
避免:方法同名(如果同名,新增优先)

延展

为了方法不声明就可以直接调用,通过类目的形式实现延展在实际开发中不用,了解即可

代理模式(delegate代理)

解决问题:本身自己做不了的事情,找一个代理商替自己完成,这种模式就教代理模式。
1.构成:协议、代理商、委托者
2.委托过程:委托,找到符合协议的,代理商区完成特点的行为。

通知中心

分为:
1.发布通知
2.注册通知,被注册的方法,自动执行

初级内存管理

造成闪退的原因:

1.内存溢出
2.野指针异常

内存管理的方式:

1.垃圾回收(GC):程序员只需要开辟内存空间,不需要用代码显示地释放,系统来判断哪些空间不在被使用,
2.引用计数(Manual Reference Count):内存的开辟和释放都由程序代码进行控制。相对垃圾回收来说,对内存的控制更加灵活,可以在需要释放的时候及时释放,对程序员的要求较高,要熟悉内存管理的机制。
3.自动引用计数(Auto Reference Count):IOS 5.0的编译器特性,它允许用户只开辟空间,不用去释放空间。它不是垃圾回收!它的本质还是MRC,只是编译器帮程序员默认加了释放的代码。

黄金法则:

当调用了alloc、new、copy、retain一次,使用完该对象,相应的应该调用release、autorelease一次。即增加方法与减少方法需要配对使用。
内存管理主要解决两个问题:野指针与内存泄露
1.野指针:一般理解的野指针概念指的是对象已被释放或指针变量指向的对象已不存在,然后向该对象发出一个SEL消息,导致app异常退出。
2.内存泄漏:在堆上分配一个对象使用完成后,程序员忘记手动释放或是对象之间存在相互strong引用关系,程序已退出,而对象还未被销毁问题。

注意

1:没有使用的对象,不需要释放

1
2
3
4
Persom * p = [[Persom alloc] init];
NSString * name = p.pName;
[p release];
[name release];

2:以个方法返回一个对象是,对象会自动释放

1
2
3
4
- (NSString * )gexx{
NSString * str=[[[NSString alloc]initWithFormat:@"%@",@"123"]autorelease];
return str;
}

3:不是自己创建的对象,而是通过引用传递产生的对象,不需要释放

NSError * error;
NSString * str = [[NSString alloc] initWithContentsOfFile:nameencoding:NSUTF8StringEncoding error:&error];
if (str==nil) {
  //处理错误
}    
[str release];

4:实现开发中不要自作聪明,自己写销毁方法
5:不要尝试去集合中的数据进行内存管理
6:父对象被销毁,子对象也跟着销毁,不必自己在释放

小结

内存管理三个方法:GC、MRC、ARC(IOS使用MRC、ARC)
内存管理的方法:alloc、new、copy计数器1
retain +1
release -1
autorelease 某一时刻自动-1
retacount返回某个对象计数器值,一般不调用这个方法
当计数器为0,会执行dealloc方法
黄金法则:谁创建谁释放