iOS基础和原理笔记留存

类的格式

类的声明和实现

.h文件格式

@interface 类名:NSObject{
    # 成员变量
}
#属性

@end

.m文件格式

@implementation 
# 方法的实现
@end
在声明或实现一个类的方式时,需要用“+”或“-”在方法开头
  • “+”表示类方法
  • “-”表示对象方法
类方法的调用

导入头文件,任何地方都可以通过类名调用类里面的方法:如[类名 类方法]

对象方法的调用

调用对象方法的时候,必须现有对象去调用它

如何创建一个对象

格式:[类名 new]
工程方法创建对象:Person *person = [Person person];

结构体

常用的结构体

CGSize;CGPoint;CGRect;NSRange

CGSize 宽高
CGSize size = {320, 480};
NSlog(@"%@",NSStringFromSize(size));

CGSize size = CGSizeMake(420,320);
NSLog(@"%@",NSStringFromSize(size));
CGPoint 定义一个点
CGPoint point = {320, 480};
NSlog(@"%@",NSStringFromPoint(point));

CGPoint point = CGPointMake(420,320);
NSLog(@"%@",NSStringFromPoint(point));
CGRect 定义一个点
CGRect point = CGRectMake{20, 20, 100, 200};
/*
    struct CGRect{
        CGPoint orgin;//坐标
        CGSize size;//宽高
    }
    typedef struct CGRect CGRect;
*/
NSLog(@"%@",NSStringFromRect(rect));
NSRange 范围/幅度
/*
    struct _NSRange {
        NSInteger loction;//位置
        NSInteger length;//长度
    } NSRange;
*/
NSRange range = {2,5};
NSLog(@"%@",NSStringFromRange(range));

C语言的方法用在OC中时,不属于任何对象,声明即可使用

原子性

  • atomic:原子性,中途写入中断,取消写入,写入失败
  • nonatomic:非原子性,中途写入中断,写入多少算多少

C语言 判断字符串方法

  • isalpha()是否为字母字符
  • isdigit()是否为数字字符
  • isnumber()是否为数字字符
  • isalnum()是否为字母或数字字符
  • islower()是否为小写字母
  • isupper()是否为大写字母
  • toupper()转为大写
  • islower()转为小写

id

是一个泛型指针,可以指向任何一个指针,任何类型,任何对象

字符串

如何将C语言中的字符串转换成OC中的字符串

<1> 输入

char c[1000];
    scanf("%s",c);
    NSString *str = [[NSString alloc] initWithUTF8String:c];

<2> 转化

const char *P = "123123";
    NSString *string = [[NSString alloc] initWithUTF8String:P];
    NSString *string2 = [NSString stringWithUTF8String:P];
一段字符串在字符串中的位置和长度
NSString *str = @"00000111222333";
    NSRange range = [str rangeOfString:@"1111"];
    NSLog(@"1111在str里面的位置为%@",NSStringFromRange(range));
    //若想输出“1111“所在的位置和长度
    NSLog(@"%ld", range.location);// ->5
    NSLog(@"%ld",range.length);// ->4
字符串的创建
1. 简单的创建
//初始化 NSString *str = [[NSString alloc] init];
    // NSString *str = [NSString string];
    // NSString *str = @"hello world";
2.字符串给字符串赋值
NSString *str1 = @"123456";
    NSString *str2 = [[NSString alloc] initWithString:str1];
    NSString *str3 = [NSString stringWithString:str2];
3. 通过拼接给字符串赋值
NSString *str1 = [[NSString alloc] initWithFormat:@"%ld%@", 1000, @"phone"];//str1:1000phone
    NSString *str2 = [NSString stringWithFormat:@"%ld%@", 1000, @"phone"];//str2:1000phone
    NSString *str3 = @"12345";
    NSString *str4 = @"helloworld";
    NSString *str5 = [NSString stringWithFormat:@"%@%@",str3, str4];
4. 从文件中读取
NSError *err = nil;
    NSString *str = [[NSString alloc] initWithContentsOfFile:@"文件路径" encoding:NSUTF8StringEncoding error:&err];
    if (err == nil) {
        NSLog(@"文件f读取成功");
    }else{
        NSLog(@"文件读取失败");
    }
    //若想知道错误信息加上这表语句,localizedDescription方法会提取有用的信息
    NSLog(@"错误信息为%@", [err localizedDescription]);
5. 通过URL路径获取字符串
NSString *urlPath = @"www.baidu.com";
    //将字符串路径转成URL
    NSURL *url = [NSURL URLWithString:urlPath];
    NSError *err = nil;
    NSString *str = [[NSString alloc] initWithContentsOfURL:urlPath encoding:NSUTF8StringEncoding error:&err];
    if (err) {
        NSLog(@"读取失败");
        NSLog(@"%@", [err localizedDescription]);
    }else{
        NSLog(@"读取成功");
        NSLog(@"str=%@", str);
    }

字符串的方法:NSString类型

1. 字符串的拼接
每次拼接字符串都重新开辟一段空间
NSString *str1 = @"1000";
    NSString *str2 = @"phone";
    //1. NSString *str = [NSString stringWithFormat:@"%@%@", str1, str2];
    //2. NSString *str = [str1 stringByAppendingString:@"hello"];
    //3. NSString *str = [str1 stringByAppendingString:str2];
2. 字符串的搜索
NSString *urlPath = @"http://im.qq.com/qq=123";
    NSRange range = [urlPath rangeOfString:@"qq="];
    NSInteger loc = range.location;//位置:5
    NSInteger length = range.length;//长度:3
3. 字符串的截取
NSString *str = @"0123456789";
    NSString *str1 = [str substringFromIndex:5];//开区间(不包含边界的这个数)
    NSLog(@"%@",str1);
    //str里第5个位置开始之后的字符串全截取,即56789
    NSString *str2 = [str substringToIndex:5];//闭区间(包含边界的这个数)
    //只截取str里前5个字符,即01234
    NSLog(@"%@",str2);
    NSRange range = NSMakeRange(3, 2);
    NSString *str3 = [str substringWithRange:range];//开区间
    //截取str里第3个文职开始长度为2个的字符,即34
    NSLog(@"%@",str3);
4. 字符串的比较
如果两个字符串的内容一样,那么内存只会开辟一块空间储存,是因为两个两个字符串的指针都指向同一块内存空间,如果字符串不一样,在内存里会有两块空间
NSString *str0 = @"abc";
    NSString *str1 = @"abc";
    NSString *str2 = @"abcb";
    NSMutableString *str3 = [[NSMutableString alloc] initWithString:@"abc"];
    
    NSLog(@"指针所指向对象的地址:%p",str0);
    NSLog(@"指针所指向对象的地址:%p",str1);
    NSLog(@"指针所指向对象的地址:%p",str2);
    NSLog(@"指针所指向对象的地址:%p",str3);
    
    //<1> 地址比较 通过==比较的是两个字符串的地址
    if (str0 == str1) {//此时一样,地址内容都一样
        //两个字符串地址一样
    }else{
        //两个字符串地址不一样
    }
    if (str0 == str3) {//此时地址不一样,虽然内容一样
        //两个字符串地址一样
    }else{
        //两个字符串地址不一样
    }
    //<2> 内容比较
    if ([str0 isEqualToString:str1] && str0 == str2) {//此时地址和内容都一样
        //地址和内容都一样
    }
    //<3> compare方法比较
    NSString *str0 = @"qqww";
    NSString *str1 = @"abc";
    NSComparisonResult result = [str0 compare:str1];
    if (result == NSOrderedAscending) {
        //前面一个字符串小于后面的字符串
    }else if (result == NSOrderedSame){
        //前面一个字符串等于后面的字符串
    }else{
        //前面一个字符串大于后面一个字符串
    }

内容一样,地址不一定一样;
地址一样,内容一定一样

5. 字符串导入
NSString *str = @"床前明月光";
    NSError *err = nil;
    [str writeToFile:@"文件路径" atomically:YES encoding:NSUTF8StringEncoding error:&err];
    if (err) {
        //导入失败
    }else{
        //导入成功
    }
获取字符串的长度
NSinteger length = [str length];
获取字符串中某一个位置的字符
unichar c = [str characterAtIndex:0];
查找前缀/后缀是否存在
BOOL isExistPrefix = [str hasPrefix:@"前缀"];
    BOOL isExistSuffix = [str hasSuffix:@"后缀"];
将字符串转化成各种值

NSString *str0 = @"1440";
1. 转成int类型:int value = [str0 intValue];
2. 转成float类型:float value = [str0 floatValue];
3. 转成double类型:double value = [str0 doubleVlaue];
4. 转成NSInteger类型:NSInteger value = [str0 integerVlaue];
5. 转成longlong类型:long long value = [str0 longLongVlaue];
6. 转成BOOL类型:BOOL value = [str0 boolValue];

将一个字符串最前面的数字提取出来
NSString *str = @"10.1Qian 123phone";
    double value1 = [str doubleValue];
    NSLog(@"%f",value1);//10.100000
    int value2 = [str intValue];
    NSLog(@"%d",value2);//10
    //字符串str前面的数字不为0,则为真,否则为假
    BOOL isReal = [str boolValue];
    NSLog(@"%d", isReal);//1

可变字符串的方法

创建初始化
NSMutableString *str = [[NSMutableString alloc] initWithCapacity:0];
    [str setString:@"123"];//str = 123
可变字符串的拼接
NSMutableString *str = [[NSMutableString alloc] initWithCapacity:0];
    [str appendString:@"12345"];//str = 12345
    [str appendFormat:@"%@%d",@"456",567];//str = 1234545656
可变字符串的删除
NSString *str = @"I Love You";
    NSMutableString *str1 = [[NSMutableString alloc] initWithString:str];
    NSRange range =[str1 rangeOfString:@"Love"];//love的位置和长度
    [str1 deleteCharactersInRange:range];//删除Love
    //str = I You
可变字符串的替换和插入
这里的range承接自上面
[str replaceCharacterInRange:range withString:@"hate"];//I hate You
    [str insertString:@" miss" atIndex:range.location + range.length];//str = I hate miss You
    [str insertString:@"no" atIndex:5];//str = I hatnoe miss You

不可变数组的使用

字符串和数字混用(字符串分割后放到数组中)
NNString *str = @"I-love-you";
    NSArray *array = [str componentsSeparatedByString:@"-"];//把str用“-”分割后存放于array中
    NSArray *array = @[@"welcome", @"to", @"china"];
    NSString *str = [array componentsJoinedByString:@" "];//把array用空格放到字符串str中形成一个字符串
创建数组
创建完了后,会给数组开辟一块空间,但是里面没东西,并且创建完了以后这块空间里面的东西不可被修改
NSArray *array0 = NSArray.new;
    NSArray *array1 = [NSArray new];
    NSArray *array2 = [[NSArray alloc] init];
    NSArray *array3 = [NSArray array];
给数组添加对象,nil相当于C语言中的“\o”,平道nil后,nil后面的内容无效,下面数组实际指望里添加了两个对象
Person *person1 = [[Person alloc] init];
    Person *person2 = [[Person alloc] init];
    Dog *dog1 = [[Dog alloc] init];
    NSArray *array1 = [[NSArray alloc] initWithObjects:person1, person2, nil, dog1];
    //NNString、NSArray、NSDictionary正常来讲,每一个初始化方法都对应一个类方法,但NSArray里,有一个arrayWithObject的类方法,但初始化方法里面没有
    NSArray *array2 = [NSArray arrayWithObject:person1];
通过数组创建数组
//对象方法
    NSArray *tempArray = [NSArray arrayWithObjects:@"one", @"two", nil];
    NSArray *array0 = [[NSArray alloc] initWithArray:tempArray];
    //类方法
    NSArray *array1 = [NSArray arrayWithArray:tempArray];
从文件里读取数组
**文件里面的数据必须按照一定得格式存储,否则没法读取**
NSArray *array = [NSArray arrayWithObjec:@"one", @"two", nil];
    [array writeToFile:@"文件路径" atomically:YES];
    NSArray *array1 = [[NSArray alloc] initWithContentsOfFile:@"路径"];//如果路径不存在,写失败,如果文件不存在,会创建一个新文件,并将数据写入,如果文件和路径都存在,直接写入
数组的遍历和简单使用
NSArray *array = @[@"one", @"123", @"你好"];
    //1. 判断数组中元素个数
    NSInteger arrayCount = [array count];
    //2. 通过索引获取具体问之的对象
    NSString *str = [array objectAtIndex:2];
数组遍历
1. for循环
for(NSInteger i = 0;i<[array count];i++)
    {
        NSString *tempStr = [array objectAtIndex:i];//或者:NSString *str = array[i];
        NSLog(@"%ld:%@", i, tempStr);
    }
2. 快速枚举
/* for(type *object in collection){...} */
    //获取某一个对象具体的索引:-(NSInteger)indexOfObject:(id)anObject
    for(id object in array){
        NSInteger index = [array indexOfObject:object];
        NSLog(@"快速枚举:%ld:%@", index, object);
    }
3. block遍历
[array enumerateObjectUsingBlock:^(id obj, NSInteger idx, BOOL *stop){
        NSLog(@"block-%ld:%@", idx, obj);
    }];
重新description方法
- (NSString*)description{
        NSString *des = [NSString stringWithFormat:@"age=%ld name=%@", self.age, self.name];
        return des;
    }

可变数组的使用

可变数组的初始化
1. NSMutableArray在初始化创建对象时,可以使用NSArray继承过来的方法,即

NSMutableArray *array = [[NSMutableArray alloc] init];

2. 下面2个方法是NSMutableArray自己扩充的方法,添加完对象后,可以往里面添加或删除对象
NSMutableArray *array1 = [[NSmutableArray alloc] initWithCapacity:0];
    NSMutableArray *array2 = [NSMutableArray arrayWithCapacity];
3. 通过addObject:方法往数组里添加对象
[array addObject:@"one"];
4. 用removeObject:移除某一个对象

[array removeObject:@"hello"];

5. 交互数组里面2个对象的位置

[array exchangeObjectAtIndex:2 withObjectAtIndex:5];

6. 将一个数组添加到一个可变数组
NSMutableArray *mutArr = [NSMutableArray arrayWithObjects:@"one", nil];
    NSArray *array = @[@"1", @"2"];
    [mutArr addObjectsFromArray:array];
7.firstObject将数组里面的第1个对象取出来

NSString * strOne = [array firstObject];

8.lastObject获取最后一个对象

NSString *strLast = [array lastObject];

9. removeLastObject移除最后一个对象

[mutArr removeLastObject];

10. removeAllObjects 删除足足里面所有对象

[mutArr removeAllObjects]

11. 插入对象

[mutArr insertObject:@"123" atIndex:4];

可变数组的排序
NSMutableArray *array = [NSMutableArray arrayWithObject:@"123", @"234", nil];
    for(int i = 0; i < [array count]; i++){
        for(int j = 0; j < [array count] - i - 1; j++ ){
            NSString *str1 = [array objectAtIndex:j];
            NSString *str2 = [array objectAtIndex:j+1];
            NSComparisonResult result = [str1 compare: str2];
            if (result == NSOrderedDescending){
                [array exchangeObjectAtIndex:j withObjectAtIndex:j+1];
            }
        }
    }
    NSLog(@"%@", array);

字典

字典初始化
1. 第一种创建方式
NSDictionary *dic0 = NSDictionary.new;
    NSDictionary *dic0 = [NSDictionary new];
    NSDictionary *dic0 = [[NSDictionary alloc] init];
    NSDictionary *dic0 = [NSDictionary dictionary];
2. 字典里value-key配对出现的,可以通过key找到对应的value
NSDictionary *dic = [[NSDictionary alloc] initWithObjectAndKeys:@"175":@"height", @"150":@"weight", nil];
    NSLog(@"%@", dic);//height = 175; weight = 250;
    //通过字典里的key找到对应的值
    NSString *height = [dic objectForKey:@"height"];
    NSLog(@"height=%@", height);//height = 175
3. 通过字典穿甲字典

NSDictionary *dic4 = [[NSDictionary alloc] initWithDictionary:dic];

4. 通过两个数组创建字典
NSArray *values = @[@"175", @"小明"];
    NSArray *keys = @[@"height", @"name"];
    NSDictionary *dic5 = [[NSDictionary alloc] initWithObjects:values forKeys:keys]
5. 获取字典里所有的键值
NSArray *values = [dic allValues];
    NSArray *keys = [dic allKeys];

可变字典

创建

NSMutableDictionary *mutableDic = [[NSMutableDictionary alloc] initWithCapacity:0];

一般用字符串作key,而value可以使任何对象
//1.字符串
    [mutableDic setObject:@"123" forKey:@"string"];
    //2.数组
    NSArray *array =@[@"123", @"456"];
    [mutableDic setObject:array forKey:@"array"];
    //3.取出数组
    NSArray *values = [mutableDic objectForKey:@"array"];//values = (123,456)
移除所有的键值对

[mutableDic removeAllObjects];

字典的遍历
[dic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop){
        NSLog(@"key = %@ value = %@", key, obj);
    }];

集合NSSet

创建
//1.
    NSSet *set0 = NSSet.new;
    //2.
    NSSet *set1 = [NSSet new];
    //3.
    NSSet *set2 = [[NSSet alloc] init];
    //4.
    NSSet *set3 = [NSSet set];
    //5.
    NSSet *set4 = [[NSSet alloc] initWithObjects:@"hello", @"world", nil];//{(hello,world)}
    //6.
    NSSet *set5 = [[NSSet alloc] initWithObjects:@"hello", @"hello", nil];//{(hello)} 数组可以放重复的东西,集合不可以
集合元素的个数

NSInteger count = [set5 count];//1个

是否存在,存在为1,不存在为0

BOOL isExist = [set5 containsObject:@"hello"]//1;

anyObject 随机从集合里取一个对象并返回
NSString *setString = [set4 anyObject];
    NSLog(@"%@", setString);
    //经打印几次都是同一个对象,但这个对象时随机的

点语法

car.brand:@"奥迪";//实际调用的是[car setBrand:@"奥迪";] 通过点语法调用set方法修改_brand的值

car.brand = @"BMW";//set方法,car.brand右边有"=",调用set方法
    NSLog(@"%@", car.brand);//get方法,右边没有”=“,调用的get方法
    
    NSInteger price = [car price];//get方法
    NSInteger price = car.price;//点语法获取
总结

编写set方法和get方法时,set方法必须按照规范来写,才能通过点语法调用set方法,而get方法可以随便写,但是为了规范,get方法也得按规范写

//标准的set和get方法
    [person setAge:15];//set方法
    NSLog(@"age= %ld", [person age]);//get方法
    //点语法
    person.age = 51;//set方法
    NSLog(@"age = %ld", person.age);

property和synthesize的使用

@property NSString *name;
//等价于
- (void)setName:(NSString*)name;
- (NSString*)name;
//声明时如果用`@property`,系统会自动展开标准的set和get方法
synthesize name = _name;
//等价于
- (void)setName:(NSString*)name{
    _name = name;
}
- (NSString*)name{
    return _name;
}
// @synthesize 会自动展开标准的set和get方法
synthesize详解
  1. @synthesize name = _name: name等于我们声明的全局变量_name
  2. @synthesize name: 等价于@synthesize name = name;虽然我们没有声明name的全局变量,但这么一写,会自动生成一个name的成员变量,但name因为并没有在头文件里声明,故私有的,而不是被保护的

继承

类别和扩展

在OC里面没有多继承,只有单继承,但可以用类别扩展实现

扩展:不能加成员变量,只能加方法
作用:能够给一些我们不嫌或不能修改的类添加方法,类别扩展,相当于这个类的父类。

类别扩展可以模拟实现多继承,我们可以为一个写好的A类添加一些方法,但不能添加成员变量,这个类可以继承他父类的成员变量和方法,他自己扩展的类别相当于这个类的继父,无法给这个类添加成员变量,但可以给这个类添加方法

public、protected、privite
  1. public:公有类,任何地方都可以访问
  2. protected:受保护的类,只有自己的类和子类可以访问
  3. privite:私有类,只有自己的类可以访问,子类不会继承父类

如果声明的全局变量,是@protected类型的可以被子类继承,如果只是通过@property和@synthesize来关联的成员变量,它是@private类的,不能被子类继承
重写,如果子类里面重写了父类里的方法,那么调用的是子类的方法,如果子类并未重写,则调用的是父类的方法

多态

A为父类,B类和C类继承自A类,都是A的子类,则写一个A类的函数,则B类和C类都可以调用

OC私有方法

声明全局变量时,若NSInteger_a 和_b都是@protected类,而NSInteger_add和_sub是@private类的,则写get和set方法时

@property (nonatomic, readwrite) NSInteger a;
@property (nonatomic, readonly) NSInteger b;

@property (nonatomic, readwrite) NSInteger add;
@property (nonatomic, readonly) NSInteger sub;
//nonatomic 是非原子性,atomic是原子性
  1. @atomic:能保证线程安全,同一个方法有可能同时有几个线程去访问,atomic能保证同时(某一时刻)只有1个线程在访问,atomic会消耗性能
  2. @nonatomic:虽然不能保证线程安全,但我们知道下面的属性访问时不会有多个线程同时访问,我们通常使用nonatomic

*readonly:只读方法

类的复合

Car类,Wheel类,Engine类都是集成自NSObject类

  1. 先写Wheel类和Engine,并重写各自的description方法
  2. 把Wheel类和Engine头文件导入Car类,则在Car类中可调用Wheel类和Engine类

内存管理

为什么要对内存进行管理?

及时硬件越来越强大,但是内存始终是有限的,如果不对其进行管理,内存会越积越多,最终导致程序崩溃

NSLog(@"dog:%@",dog);

打印dog描述信息,实际上打印的是对象的描述信息,但我们通常说dog就是对象,这是一个习惯性说法,实际上dog只是一个指向对象的指针,打印的时候直接写dog,实际上是给dog发送了一条description消息,直接打印dog等价于[dog description]

ReturnCount
OC里面new和alloc会开辟空间

C里面是malloc开辟空间,和malloc对应的有一个free(void*)释放空间

MRC和ARC

ARC:不是Java里面垃圾回收机制,而是介于手动管理和垃圾回收机制之间的一种回收机制
MRC:手动管理,允许发送release消息,(消息就是函数,也叫方法)

内存泄露

如果我们不再使用一个对象,应该给这个对象发送release消息,发送消息就是让某个对象调用某个方法
例:

Dog *dog = [[Dog alloc] init];
    //如果没有[dog release];那么dog就有内存泄露
僵尸对象

僵尸对象:一个对象已经不存在了,但是我们还给先前指向这个对象的指针发送消息,这时候会崩溃
例:

Dog *dog = [[Dog alloc] init];
    [dog release];
    NSLog(@"dog=%@", dog);

当出现僵尸对象时,控制台会打印虾米的信息,意思是Dog这个创建的对象已经被release了,deallocation就是被释放的意思-[Dog respondsTOSelector:]message sent to dealloction instance xxx

过度释放
Dog *dog = [[Dog alloc] init];
    [dog release];
    [dog release];//过度释放,一个alloc只能对应一个release,过度释放会导致崩溃
@class name; #import "name"

通过@class这个关键词告诉这个头文件,哪有这么一个类,如果通过#import这种方式导入,可能会出现循环导入,导致编译没法通过
在.h文件通过@class告诉A类有B类存在,但是.m文件还是要将B.h头文件导入进来,方能使用

reation和release

reation:使对象拥有使用权,使retainCount+1
release:释放使用权,使retainCount-1

alloc和dealloc

alloc:开辟一段内存空间
dealloc:对应alloc,当retainCount=1时,再次给对象发送release消息时,就会调用dealloc函数,将对象的空间释放掉

- (void)delloc{
    NSLog(@"%@", __func__);
    [super delloc];
}

这是我们重新的父类的-(void)delloc函数,系统会自动的去调用,我们不能手动去调用它

set和get的标准写法

以Car类为例,把Car在Person.h里@class下,再把Car.h导入Person.m里

- (void)setCar:(Car*)car{
    if(_car != car){//判断的是地址不一样
        [_car release];//先给上一个_car发送release消息
        _car = [car retain];
    }
}

- (Car*)car{
    return _car;
}

在一个类里如果有全局变量的指针,定义为全局变量的指针后,马上从-(void)delloc函数里给它发送release,如果这个指针始终为nil,那么发送的release不起任何作用

自己创建的类重写NSCopying和NSMutableCopying协议里的方法
//NSCopying协议里的方法
- (id)copyWithZone:(NSZone*)zone{
    A *a = [[A alloc] init];
    return a;
}

- (id)mutableCopyingWithZone:(NSzone*)zone{
    A *a = [[A alloc] init];
    return a;
}
Property内存管理
assign

直接赋值,主要用在基本数据类型,引用计数不变,指针指向同一个地址

什么情况下需要release?

有alloc、new、retain、copy、mutableCopy的情况下都需要release或autorelease

什么情况下载dealloc里面给对象发送release?

如果对象时全局变量,就在dealloc发送release消息,全局的变量必须在dealloc里面发送release,因为全局变量在整个类里面任何方法里面都可以使用,如果在对象被销毁之前,就将此全局变量销毁,调用的时候就在发送崩溃
如果一个对象是在函数里面的局部变量,这个指针使用完后,如果不再使用,马上发送release消息

如果想对一个对象copy或者发送mutableCopy消息,应该怎么做?

分两种情况:

  1. 系统类:如NSString、NSArray等,这种系统类创建的对象直接可以copy或者发送mutableCopy,因为这些系统类已经采用NSCopying、NSMutableCopying这两个,并且实现了这个两个协议里面的方法
  2. 自己创建的类:这种情况下,需要我们自己采用NSCopying、NSMutableCopying这俩协议,并且实现这俩协议里面的方法,如果不采用协议,或者采用了协议里面的方法,没法copy或者mutableCopy,会崩溃
NSString、NSArray、NSDictionary里copy,retain和mutableCopy
  1. 系统类里面的不可变字符串,不可变数组,不可变字典,使用retain和copy效果是一样的,即不可变的字符串、数组、字典使用copy和retain都属于浅拷贝,只有mutableCopy才是深拷贝
  2. 在类的声明时,写retain和copy效果一样,但习惯于写copy
  3. 不可变的字符串、数组、字典甚至我们自己创建的类,以后都不能用引用计数来作为依据,什么时候该示范对象,什么时候不该释放对象,引用计数知识一个原理,但系统的实现我们并不清楚,以后只需要按照黄金法则来使用即可
黄金法则
  1. 以后给指针赋值时,只有有alloc、new、mutableCopy,retain,只有有这些关键词,我们就需要再适当的时候给这些对象(指针)发送release,释放使用权
  2. 全局变量统统在dealloc里面发送release消息;局部变量什么时候不用,立即发送release消息即可
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值