我的iOS开发之Objective-C第8天之ARC&&类目

1、ARC 中lifetime修饰词

  • 默认是__strong。只要对象还有强引用,该对象“活着”
  • __weak不保留对象,只是简单引用。weak对象将被设置nil,当对象没有任何强引用的时候。
  • __unsafe_unretained 不保留对象,只是简单引用。但是不设置为nil,当对象没有任何强引用得时候。如果对象被销毁,__unsafe_unretained的对象将会野指针。
  • __autoreleasing 用于标识id*的引用参数,或者需要自动释放的返回的对象。

2、什么是ARC?

  • Automatic Reference Counting,自动引用计数
  • 在工程中使用ARC非常简单:只需要像往常那样编写代码,只不过永远不写retain,release和 autorelease三个关键字就好~这是ARC的基本原则。
  • ARC与其他语言的”垃圾回收”机制不同。ARC:编译器特性;“垃圾回收”运行时特性
    [更多的了解ARC(http://blog.csdn.net/kaitiren/article/details/17219957)

3、ARC判断准则
只要没有强指针指向对象,对象就会被释放。
注意:当使用ARC的时候,暂时忘记“引用计数器”,因为判断标准变了。


4、何为强弱指针

  • __strong:强指针,所有的指针默认就是强指针
  • __weak:弱指针

5、lifetime修饰词在实际中的运用


void Fun1()
{
//    内存没有被使用时立即释放
    {
//        默认是__strong
    Student *stu=[[Student alloc] init];
    stu.name=@"李四";
    }
//    此处stu为局部变量在栈区,花括号关闭释放,同时内存没有强指针指向,内
//存即释放

}

void Fun2()
{
    {
//    弱指针指向内存空间,根据ARC判断准则只要没有强指针指向对象,对象就会
//释放 ,弱指针当然留不住内存,内存立即释放,当然,这样做没有什么意义,
//只是说明一下只有强指针指向对象,对象才不释放
        __weak Student *stu=[[Student alloc] init];
        stu.name=@"李四";
    }

}
void Fun3()
{
//    有强指针指向对象不会立即释放内存
    Student *stu;
    {
         Student *stu1=[[Student alloc] init];
        stu1.name=@"李四";
        stu=stu1;
//        现在对象被stu1和stu强指针指向
    }
    //花括号关闭,stu1释放,不过还有stu强指针指向,不能释放
    int i=0;
    i++;
}
//stu也释放,现在对象没有强指针指向,立即释放
void Fun4()
{
   __weak Student *stu;
    {
        Student *stu1=[[Student alloc] init];
        stu1.name=@"李四";
        stu=stu1;
    }
//    此处释放内存
    int i=0;
    i++;

}
void Fun5()
{
    {
// 返回野指针 不安全  会概率性崩溃同时,内存立即释放
//不同于弱指针,内存释放,弱指针立即等于nil;
//而野指针值不变,不过内存释放了
    __unsafe_unretained Student *stu=[Student new];

    }
}

void Fun6()
{
    @autoreleasepool {

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

    @autoreleasepool {

        Fun4();

    }
    return 0;
}
6、ARC下循环引用问题

person.h

@interface Person : NSObject
//dog是strong 强指针
@property (nonatomic,strong) Dog *dog;
@end

person.m
@class Person;
@interface Dog : NSObject
//狗的主人 也是strong 强指针
@property (nonatomic,strong) Person *owner; @end

main.m
int main(int argc, const char * argv[]) {
    @autoreleasepool {
 Person *p = [Person new]; 
Dog *d = [Dog new]; p.dog=d;
 d.owner=p;
}
    return 0;
}

运行结束会发现person和dog都无法释放

解决方案
循环引入的对象中其中一个对象设置为strong 另一个设置为weak

7、ARC下@property参数

  • strong : 用于OC对象, 相当于MRC中的retain
  • weak : 用于OC对象, 相当于MRC中的assign,不过释放时,weak变自动=nil,assign不能
  • assign : 用于基本数据类型, 跟MRC中的assign一样
  • copy: 一般用于NSString, 跟MRC中的copy一样
    在ARC情况下解决”循环retain”的问题:@property一边用strong,一边用weak。
    在MRC情况下解决”循环retain”的问题:@property一边用retain,一边用assign(可见第7天总结)。

分类(Category)
1、类别概念

  • Category有很多种翻译: 分类 ,类别 ,类目,范畴 (一般叫分类)
  • Category是OC特有的语法, 其他语言没有的语法(类似于C#语言中的”扩展方法”和”partial” 关键字)

2、类别的作用

  • 在不修改原有的类的基础上增加新的方法
  • 一个庞大的类可以分模块开发
  • 一个庞大的类可以由多个人来编写,更有利于团队合作

3、类目的局限性

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

4、类目的作用

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

首先来看一个例子

student.h

#import <Foundation/Foundation.h>

@interface Student : NSObject
-(void) test;
@end
@interface Student (Student1)
-(void ) test1;
@end
@interface Student (Student2)
-(void) test2;
@end
@interface Student (Student3)
-(void) test3;
@end

student.m

#import "Student.h"
@implementation Student
-(void)test{
    NSLog(@"test");
}
@end

student+student1.m

#import "Student.h"

@implementation Student (Student1)
-(void)test1{
    NSLog(@"test1");
}
@end

student+student2.m

#import "Student.h"

@implementation Student (Student2)
-(void)test2{
    NSLog(@"test2");
}
@end

student+student3.m

#import "Student.h"

@implementation Student (Student3)
-(void)test3{
    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];
        [stu test3];
          }
    return 0;
}

注意观察,只有一个。h文件。
1个.h文件对应多个.m文件

另外下面是今天自己做的作业,大家参考下
NSString+MyStringCategory.h

#import <Foundation/Foundation.h>

@interface NSString (MyStringCategory)
/**
 *  字符串首字母大写的方法
 *
 *  @return NSString类实例
 */
-(NSString *)Capitalized;
/**
 *  单词首字母大写的方法
 *
 *  @return 一个NSString实例
 */
-(NSString *) capitalized;
@end

NSString+MyStringCategory.m

#import "NSString+MyStringCategory.h"

@implementation NSString (MyStringCategory)

-(NSString *)Capitalized{
   char a=[self characterAtIndex:0];
    char b=a-32;
    NSString *s1=[NSString stringWithFormat:@"%c",a];
    NSString *s2=[NSString stringWithFormat:@"%c",b];
    NSMutableString *str=[NSMutableString stringWithString:self];
    NSRange range={0,1};
    if (a>=97&&a<122) {
        [str replaceOccurrencesOfString:s1 withString:s2 options:NSLiteralSearch range:range ];
    }
    return str;
}
-(NSString *) capitalized{
    NSString *str=[NSString stringWithString:self.capitalizedString];
    return str;
}
@end
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值