OC-分类、扩展、ARC

1、分类

1.1、将一个复杂的类分成若干个模块儿,其中每个模块被称为一个分类
1.2、分类的作用是降低耦合度
1.3、分类的语法(分类只能有方法,不能定义属性)
1.4、在主函数中,只能看到一个主类不会看到分类
1.5、分类中不能定义成员变量或属性
1.6、可以给没有源代码的类添加分类

实例代码
主类(SHFraction类):

SHFraction.h:
#import <Foundation/Foundation.h>

@interface SHFraction : NSObject
@property int n;
@property int d;
-(void)show;
@end
SHFraction.m:
#import "SHFraction.h"

@implementation SHFraction
-(void)show
{
    NSLog(@"%d/%d", self.n, self.d);
}
@end

分类(SHFraction+SHInit类):

SHFraction+SHInit.h:
#import "SHFraction.h"

@interface SHFraction (SHInit)
-(id)initWithN:(int)n andD:(int)d;
+(id)fractionWithN:(int)n andD:(int)d;
@end
SHFraction+SHInit.m:
#import "SHFraction+SHInit.h"

@implementation SHFraction (SHInit)
-(id)initWithN:(int)n andD:(int)d
{
    if (self = [super init])
    {
        self.n = n;
        self.d = d;
    }
    return self;
}
+(id)fractionWithN:(int)n andD:(int)d
{
    SHFraction *f = [[SHFraction alloc] initWithN:n andD:d];
    return f;
}
@end

分类(SHFraction+SHMath类):

SHFraction+SHMath.h:
#import "SHFraction.h"

@interface SHFraction (SHMath)
-(SHFraction*)add:(SHFraction*)f;
-(SHFraction*)sub:(SHFraction*)f;
-(SHFraction*)mul:(SHFraction*)f;
-(SHFraction*)div:(SHFraction*)f;
@end
SHFraction+SHMath.m:
#import "SHFraction+SHMath.h"
#import "SHFraction+SHInit.h"

@implementation SHFraction (SHMath)
-(SHFraction *)add:(SHFraction *)f
{
    SHFraction *result = [[SHFraction alloc] init];
    result.n = self.n * f.d + f.n * self.d;
    result.d = self.d * f.d;
    return result;
}
-(SHFraction *)sub:(SHFraction *)f
{
    int n = self.n * f.d - f.n * self.d;
    int d = self.d * f.d;
    return [SHFraction fractionWithN:n andD:d];
}
-(SHFraction *)mul:(SHFraction *)f
{
    return [SHFraction fractionWithN:self.n *f.n andD:self.d * f.d];
}
-(SHFraction *)div:(SHFraction *)f
{
    return [SHFraction fractionWithN:self.n *f.d andD:self.d * f.n];
}
@end

main函数:

#import <Foundation/Foundation.h>
#import "SHFraction+SHInit.h"
#import "SHFraction+SHMath.h"
#import "SHFraction+SHTransfer.h"
#import "NSObject+SHShow.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        SHFraction *f1 = [[SHFraction alloc] initWithN:3 andD:10];
        [f1 show];
        SHFraction *f2 = [SHFraction fractionWithN:1 andD:5];
        [f2 show];
        SHFraction *f = [f1 add:f2];
        [f reduce];
        [f show];
        f = [f1 mul:f2];
        [f show];

        [f tr_print];
    }
    return 0;
}

2、扩展

2.1、扩展是没有名字的分类
2.2、两种形式
    2.2.1、单独写在一个.h文件中,扩展中的成员变量是私有的,属性和方法是公有的
    2.2.2、将扩展写在主类的.m文件中,此时扩展中的成员变量和属性、方法都是私有的
2.3、与分类的区别
    2.3.1、有没有.m文件
    2.3.2、有没有成员变量或属性
2.4、与协议的区别
    2.4.1、协议可以被任何类采纳,但扩展只属于主类

实例代码
SHFraction类:

SHFraction.h:
#import <Foundation/Foundation.h>

@interface SHFraction : NSObject
@property int n;
@property int d;
-(void)show;
@end
SHFraction.m:
#import "SHFraction.h"
#import "SHFraction_SHMyExtension.h"

@interface SHFraction ()//扩展写在主类的.m文件中时,其定义的所有内容均为私有的
@property int value;//私有的
-(void)extensionMethod1;//私有的
@end

@implementation SHFraction

-(void)show
{
    NSLog(@"%d/%d", self.n, self.d);
}
-(void)extensionMethod0
{
    NSLog(@"扩展中的方法");
}
-(void)extensionMethod1
{
    NSLog(@"主类.m文件中声明的扩展方法");
}
@end

SHFraction采纳的(SHFraction_SHMyExtension)协议:

SHFraction_SHMyExtension.h:
#import "SHFraction.h"

@interface SHFraction ()
{
    int _a;
    @public//不建议使用
    int _b;
}
-(void)extensionMethod0;
@end

main函数:

main.m:
#import <Foundation/Foundation.h>
#import "SHFraction_SHMyExtension.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        SHFraction *f = [[SHFraction alloc] init];
        //f->_a = 10;
        f->_b = 20;
        [f extensionMethod0];
        f.n = 1;
        f.d = 3;
        [f show];

//        f.value = 30;
//        [f extensionMethod1];
    }
    return 0;
}

3、ARC

3.1、IOS5.0开始使用的,IOS7.0强制使用
3.2、不允许程序员调用retain、release、dealloc和aotorelease,而由编译器自动添加其调用的语句
3.3、ARC中添加的新关键字
    3.3.1、__strong 强引用(默认方式),ARC中alloc出来的空间必须用强指针指向,否则会被直接释放
    3.3.2、__weak 弱引用
    3.3.3、__unsafe_unretain//指向的空间被释放后不会清空,其余和weak一样
    3.3.4、__autoreleasing
3.4、ARC与MRC混编 Edit->convert->To Objective-C ARC...

实例代码
SHPoint类:

SHPoint.h:
#import <Foundation/Foundation.h>

@interface SHPoint : NSObject
@property int x;
@property int y;
-(id)initWithX:(int)x andY:(int)y;
-(void)show;
@end
SHPoint.m:
#import "SHPoint.h"

@implementation SHPoint
-(id)initWithX:(int)x andY:(int)y
{
    if (self = [super init])
    {
        self.x = x;
        self.y = y;
    }
    return self;
}
-(void)show
{
    NSLog(@"(%d,%d)", self.x, self.y);
}
-(void)dealloc
{
    NSLog(@"点(%d,%d)被释放了", self.x, self.y);
    //[super dealloc];//在ARC中,不允许手动调用dealloc,其调用是由ARC自动添加的
}
@end

SHCircle类:

SHCircle.m
#import "SHCircle.h"

@implementation SHCircle

@end
SHCircle.h:
#import <Foundation/Foundation.h>
#import "SHPoint.h"

@interface SHCircle : NSObject
@property(weak) SHPoint *center;
@property double radius;
@end

main函数:

main.m:
#import <Foundation/Foundation.h>
#import "SHPoint.h"
#import "SHCircle.h"

void test1()
{
    SHPoint *p = [[SHPoint alloc] initWithX:10 andY:20];
    [p show];
    //[p release];//在ARC中不需要手动编写此句
}//首先ARC自动添加[p release];,再将指针p释放

void test2()
{
    SHPoint *p1 = [[SHPoint alloc] initWithX:10 andY:20];
    [p1 show];
    SHPoint *p2;
    p2 = p1;
    //[p2 retain];//ARC中不允许手动调用retain,ARC将自动添加
    [p2 show];
}//ARC自动添加[p1 release];和[p2 release];

void test3()
{
    SHPoint *p1 = nil;
    {
        SHPoint *p2 = [[SHPoint alloc] initWithX:10 andY:20];
        [p2 show];
        p1 = p2;//ARC自动添加了[p1 retain];
    }//ARC自动添加了[p2 release];
    [p1 show];
}//ARC自动添加了[p1 release];

void test4()
{
    SHPoint *p1 = [[SHPoint alloc] initWithX:10 andY:20];
    {
        SHPoint *p2 = [[SHPoint alloc] initWithX:30 andY:40];
        [p2 show];
        p1 = p2;//在此句执行之前,ARC首先自动添加[p1 release];在执行此句之后,ARC有自动添加了[p1 retain];
    }//ARC自动添加了[p2 release];
    [p1 show];
}//ARC自动添加了[p1 release];

void test5()
{
    __weak SHPoint *p1 = nil;
    {
        SHPoint *p2 = [[SHPoint alloc] initWithX:10 andY:20];
        [p2 show];
        p1 = p2;//ARC不会自动添加[p1 retain];
        NSLog(@"%p", p1);
    }//ARC自动添加[p2 release];还将弱指针p1清空,即自动添加p1=nil;
    NSLog(@"------");
    NSLog(@"%p", p1);
}

void test6()
{
    __weak SHPoint *p = [[SHPoint alloc] initWithX:10 andY:20];//在ARC中,alloc出来的堆空间必须由强指针指向(持有),当ARC发现没有强指针指向该控件时,ARC将会把该空间释放
    NSLog(@"%p", p);
}

void test7()
{
    SHPoint *p = [[SHPoint alloc] initWithX:10 andY:20];
    SHCircle *c = [[SHCircle alloc] init];
    c.center = p;
    c.radius = 5;
}//ARC自动添加了[p release];、[c.center release]和[c release];

void test8()
{
    __unsafe_unretained SHPoint *p1 = nil;
    {
        SHPoint *p2 = [[SHPoint alloc] initWithX:10 andY:20];
        [p2 show];
        p1 = p2;
        NSLog(@"%p", p1);
    }
    NSLog(@"------");
    NSLog(@"%p", p1);
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        test8();
    }
    return 0;
}

思考练习:

编写一个SHInteger类
有一个属性int integer;还有一个方法show
给该类添加一个分类SHInit,对该类进行初始化
添加一个分类SHMath,使其具有加减乘除的功能
给该类添加一个扩展,提供将数值型属性转换成字符串的方法

解析:
SHInteger类:

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

@interface SHInteger : NSObject
@property int integer;
-(void)show;
@end
SHInteger.m:
#import "SHInteger.h"
#import "SHInteger_SHTransfer.h"

@implementation SHInteger
-(void)show
{
    NSLog(@"%d", self.integer);
}
-(NSString *)toString
{
    return [NSString stringWithFormat:@"%d", self.integer];
}
@end

SHInteger+SHInit分类:

SHInteger+SHInit.h:
#import "SHInteger.h"

@interface SHInteger (SHInit)
-(id)initWithInteger:(int)integer;
+(id)integerWithInteger:(int)integer;
@end
SHInteger+SHInit.m:
#import "SHInteger+SHInit.h"

@implementation SHInteger (SHInit)
-(id)initWithInteger:(int)integer
{
    if (self = [super init])
    {
        self.integer = integer;
    }
    return self;
}
+(id)integerWithInteger:(int)integer
{
    __autoreleasing SHInteger *i = [[SHInteger alloc] initWithInteger:integer];
    return i;
}
@end

SHInteger+SHMath分类

SHInteger+SHMath.h:
#import "SHInteger.h"

@interface SHInteger (SHMath)
-(void)add:(SHInteger*)i;
-(void)sub:(SHInteger*)i;
-(void)mul:(SHInteger*)i;
-(void)div:(SHInteger*)i;
@end
SHInteger+SHMath.m:
#import "SHInteger+SHMath.h"

@implementation SHInteger (SHMath)
-(void)add:(SHInteger *)i
{
    self.integer += i.integer;
}
-(void)sub:(SHInteger *)i
{
    self.integer -= i.integer;
}
-(void)mul:(SHInteger *)i
{
    self.integer *= i.integer;
}
-(void)div:(SHInteger *)i
{
    if (i.integer == 0)
        return;
    self.integer /= i.integer;
}
@end

SHInteger_SHTransfer协议:

SHInteger_SHTransfer.h:
#import "SHInteger.h"

@interface SHInteger ()
-(NSString*)toString;
@end

原创博文未经允许,禁止转载,否则将追究法律责任

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值