iOS开发-Day21-OC ARC&类目

1、ARC与非ARC项目的互转

  • 选择项目中的Targets,选中你所要操作的Target,选Build Phases,在其中Complie Sources中选择需要ARC的文件双击,并在输入框中输入:-fobjc-arc,
  • 如果不要ARC则输入:-fno-objc-arc

2、ARC的判断准则:

只要没有强指针指向对象,对象就会被释放。

3、指针分类:

(1)强指针:默认的情况下,所有的指针都是强指针,关键字strong

(2)弱指针:_ _weak关键字修饰的指针

声明一个弱指针如下:

__weak Person *p;

ARC中,只要弱指针指向的对象不在了,就直接把弱指针做清空操作。

__weak Person *p=[[Person alloc]  init];//不合理,对象一创建出来就被释放掉,对象释放掉后,ARC把指针自动清零。

ARC中在property处不再使用retain,而是使用strong,在dealloc中不需要再[super dealloc]。

@propertynonatomic,strong)Dog *dog;// 意味着生成的成员变量_dog是一个强指针,相当于以前的retain。如果换成是弱指针,则换成weak,不需要加_ _。

4、ARC的特点总结:

(1)不允许调用release,retain,retainCount 

(2)不允许重写dealloc,但是不允许调用[super dealloc]

(3)@property的参数:

Strong:相当于原来的retain(适用于OC对象类型),成员变量是强指针

Weak:相当于原来的assign,(适用于oc对象类型),成员变量是弱指针

Assign:适用于非OC对象类型(基础类型)

5、类目category

  1. 为什么不用继承
    继承有两个问题:

    • 第一个问题:继承的前提是这个类可以被继承,因为在Java中有些类是不允许继承的,定义成final类,同样的OC中也是有不可以继承的类
    • 第二个问题:这个类可以被继承,但是继承我们知道是侵入性的,就是我可能只是想实现一个功能,但是继承之后,子类就会把父类的所有功能(属性和方法)都继承了,这个代价太大了。没必要
  2. 类目的局限性

    • 第一,无法向类中添加新的实例变量。类别没有位置容纳实例变量。
    • 第二,名称冲突,即类别中得方法与现有的方法重名。当发生名称冲突时,类别具有更高的优先级。你得类别方法将完全取代初始方法,从而无法再使用初始方法。有些编程人员在自己的类别方法中增加一个前缀,以确保不发生名称冲突。
  3. 类目的作用
    主要用于3个目的:

    • 第一,将类的实现分散到不同文件或者不同框架中。
    • 第二,创建对私有方法的前向引用。
    • 第三,向对象添加非正式协议。

来看一个例子:

//  Student.h
#import <Foundation/Foundation.h>

@interface Student : NSObject
-(void)test;
@end

@interface Student (Student_)
-(void)test1;
@end

@interface Student (Student__)
-(void)test2;
@end
//  Student.m
#import "Student.h"

@implementation Student
-(void)test{
    NSLog(@"test1");
}
@end
//  Student+Student_.m
#import "Student.h"

@implementation Student (Student_)
-(void)test1{
    NSLog(@"test2");
}
@end
//  Student+Student__.m
#import "Student.h"

@implementation Student (Student__)
-(void)test2{
    NSLog(@"test3");
}
@end
//  main.m
#import <Foundation/Foundation.h>
#import "Student.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Student *stu=[Student new];
        [stu test];
        [stu test1];
        [stu test2];

    }
    return 0;
}

//注意上例中多个.m对应了一个.h

-
-
-
之前的ARC要是有什么不明白的还可以看一下下面这个例子

#import <Foundation/Foundation.h>
#import "Student.h"

void Fun1()
{
//    内存没有被使用时立即释放
    {
//        默认是__strong
    __strong Student *stu=[[Student alloc] init];
    stu.name=@"test1";
    }
//    此处释放内存

}

void Fun2()
{
    {
//        在这行已经释放了 弱引用
        __weak Student *stu=[[Student alloc] init];
        stu.name=@"test2";
    }

}
void Fun3()
{
//    强引用对象被使用不会立即释放内存
    Student *stu;
    {
         Student *stu1=[[Student alloc] init];
        stu1.name=@"test3";
        stu=stu1;
//        如果加入这句代码 超过} 就释放内存
//        如果不加入这句代码 在函数结束是释放
//        stu=nil;
    }
    int i=0;
    i++;

}
void Fun4()
{
   __weak Student *stu;
    {
        Student *stu1=[[Student alloc] init];
        stu1.name=@"test4";
        stu=stu1;
//        stu=nil;
    }
//    此处释放内存
    int i=0;
    i++;

}
void Fun5()
{
    {
//        返回野指针 不安全  会概率性崩溃
    __unsafe_unretained Student *stu=[Student new];
        //此处释放
        int i=0;
    }
}

void Fun6()
{
    @autoreleasepool {

     {
//         超过 自动释放池  释放内存
        __autoreleasing Student *stu=[Student new];
        stu.name=@"test6";
    }
    }
}
int main(int argc, const char * argv[])
{

    @autoreleasepool {

        Fun1();
        Fun2();
        Fun3();
        Fun4();
        Fun5();
        Fun6();

    }
    return 0;
}

-

-

-
下面附上今天的作业:

/**
 *
 *作业:为NSString类添加一个首字母大写的方法
 */
#import <Foundation/Foundation.h>
#import "NSString+Mycapital.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSString *str1=@"abcdef";//新建一个字符串str1
        NSLog(@"%@",[str1 mycapital]);//调用自己的首字母大写方法并打印
    }
    return 0;
}

//
//  NSString+Mycapital.h
#import <Foundation/Foundation.h>

@interface NSString (Mycapital)
-(NSString *)mycapital;
@end
//
//  NSString+Mycapital.m
#import "NSString+Mycapital.h"

@implementation NSString (Mycapital)
-(NSString *)mycapital{
    //提取字符串的首字符
    char temp=[self characterAtIndex:0];
    //进行首字符是否是小写字符的判断
    if (temp<=122&&temp>=97) {
        //判断通过则将temp转成大写
        temp=temp-32;
        //将大写字符储存在cap中
        NSString *cap=[NSString stringWithFormat:@"%c",temp];
        //设置首字符的范围
        NSRange range=NSMakeRange(0, 1);
        //将原字符串中得第一个字符改为cap中得字符,并返回
        return [self stringByReplacingCharactersInRange:range withString:cap];
    }else{
        //首字母不是小写是打印日志信息,并返回本身值
        NSLog(@"首字符不是小写字母");
        return self;
    }

}
@end
        /**
         *  为NSMutableArray类添加一个reverse 翻转的方法
         */
//main.m
#import <Foundation/Foundation.h>
#import "NSMutableArray+Myreverse.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
       NSMutableArray *marr=[NSMutableArray arrayWithObjects:@"a",@"b",@"c",@"d", nil];//新建一个可变数组
        [marr Myreverse];//调用自己的翻转翻转方法进行操作
        NSLog(@"%@",marr);//打印数组     
    }
    return 0;
}
//
//  NSMutableArray+Myreverse.h
#import <Foundation/Foundation.h>
/**
 * NSMutableArray的新类目
 */
@interface NSMutableArray (Myreverse)
//声明自己的翻转方法
-(void)Myreverse;
@end
//
//  NSMutableArray+Myreverse.m
#import "NSMutableArray+Myreverse.h"

@implementation NSMutableArray (Myreverse)
-(void)Myreverse{
    //从数组下标0开始循环到数组元素数量的一半
    for (int i=0; i<(self.count)/2; i++) {
        //声明一个id类型的临时变量temp
        id temp;
        //将当前循环位于的元素值赋给temp
        temp=[self objectAtIndex:i];
        //将当前循环位置的值用它翻转对应位置的值代替
        [self replaceObjectAtIndex:i withObject:[self objectAtIndex:self.count-i-1]];
        //将当前循环位置所对应位置的值用temp中的代替
        [self replaceObjectAtIndex:self.count-i-1 withObject:temp];
    }
}
@end

-15.8.10
-15.8.12

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值