分类与扩展区别 Obj-C、Swift

Obj-C 扩展

  • 在OC中经常会使用扩展,如下在.m文件中。
1. @interface 类名后面加()
2. 扩展中自动生成实现【get、set方法 以及 声明一个成员变量,成员变量命名会在属性名的前面加一个_】
3. oc中定义私有属性的方式。【那私有方法呢??直接写实现呀,还要定义干嘛?】
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) UIView *view1;

@end

@implementation ViewController

- (void)viewDidLoad {
    _view1 = [[UIView alloc]init];
    [self.view addSubview:_view1];
}

@end

复制代码
<?php 
echo "Hello World!"; 
?> 
复制代码

Obj-C 中的分类

  • 我这里新建了一个Person对象。里面什么都没有然后写了个Person的分类Person(addition)
  • 分类中只能定义方法
  • ()必须有名称

.h文件

#import "Person.h"

@interface Person(addition)
@property (nonatomic, assign) int year;
@end

复制代码

.m文件

#import "Person+addition.h"

@implementation Person(addition)

@end

复制代码

ViewController中创建对象并且进行打印。

#import "ViewController.h"
#import "Person+addition.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    Person *p1 = [[Person alloc]init];
    p1.year = 11;
    NSLog(@"%d",p1.year);
}
复制代码

这个异常信息,它通常是消息接收者找不到对应的@selector()方法。意思是get set方法都没有。

其实Xcode已经提示了。没有定义set 和get 方法【其实连申明都没有因为_year找不到~~】。我感觉这里报错会比较合适。?

但是呢。? 使用@synthesize year手动创建 set year ivar呢?会报错。【所以想要扩展属性还是乖乖的用runtime吧】

可以写@property (nonatomic, assign) int year;但是没有定义属性,只能写set 和get方法那如何应用呢?

如何使用。

  • Person.h
#import <Foundation/Foundation.h>

@interface Person : NSObject
@property (nonatomic, assign) int year;
@end
复制代码
  • Person.m文件文件没有内容

  • Person+addition.h文件

#import "Person.h"

@interface Person(addition)
@property (nonatomic, assign) int theYear;

-(int)theYear;
-(void)setTheYear:(int)theYear;

@end
复制代码
  • Person+addition.m文件
#import "Person+addition.h"

@implementation Person(addition)

-(int)theYear{
    return self.year + 1;
}
-(void)setTheYear:(int)theYear{
    self.year = theYear;
}

@end
复制代码

其实就是用 set get 方法进行一些操作。比如对里面属性赋值呀。运算等。

  • ViewController.m 中使用
#import "ViewController.h"
#import "Person+addition.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    Person *p1 = [[Person alloc]init];
    p1.theYear = 1;
    NSLog(@"myYear:%d",p1.year);
    NSLog(@"year:%d",p1.theYear);
}


@end
复制代码

打印结果

Swift

  • Swift中是没有分类的。只有扩展哦。
  • 和OC中的分类又点类似,不能定义属性,用起来像是属性但是呢 其实就是get 和set方法。但是本身不是属性。
  • 可以在扩展中定义方法。
  • 呢么看Swift中的扩展简直就是简单粗暴。
import UIKit

class Person: NSObject {
    var myYear:Int = 0;
}


extension Person{
    var year:Int{
        get{
            return myYear;
        }
        set{
            
            myYear = 22
        }
    }
    
    func log() {
        print("打印下")
    }
}

复制代码

Person的使用

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let p1 = Person()
        print(p1.year);
    }

}
复制代码

Swift中的扩展用法和OC的分类类似。而OC的扩展基本就是用于创建私有属性。 由于Swift中私有属性都是 private来申明的所以就没了?


最后 OC中的分类中的结构体有几个属性?

这里不写代码了,其实在我们经常使用的代码里就有了。说一个现象可能就想到了,那就是不能对frame的中的属性直接复制,这是为啥呢?

char *category_name                        OBJC2_UNAVAILABLE; // 分类名
char *class_name                             OBJC2_UNAVAILABLE; // 分类所属的类名
struct objc_method_list *instance_methods    OBJC2_UNAVAILABLE; // 实例方法列表
struct objc_method_list *class_methods       OBJC2_UNAVAILABLE; // 类方法列表
struct objc_protocol_list *protocols         OBJC2_UNAVAILABLE; // 分类所实现的协
复制代码
  • 原来frame是在分类中,呢么按照刚说的,先不管结构体。呢么肯定了我们使用的是get 和set 方法,而不是属性。
  • 而CGRect是一个结构体。
  • 所以我们只能进行set方法了。就有了我们平时的写法 self.view.frame = CGRectMake(0, 0, 0, 0);所以呀结构体里是没有属性的,我们只是把结构体当做参数拿来对UIView中的一些属性进行了操作。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值