分类与扩展区别 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方法都没有。

image
image

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

image

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

image

可以写@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

打印结果


image

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的中的属性直接复制,这是为啥呢?

看下面截图。

  • 原来frame是在分类中,呢么按照刚说的,先不管结构体。呢么肯定了我们使用的是get 和set 方法,而不是属性。
  • 而CGRect是一个结构体。
  • 所以我们只能进行set方法了。就有了我们平时的写法 self.view.frame = CGRectMake(0, 0, 0, 0);所以呀结构体里是没有属性的,我们只是把结构体当做参数拿来对UIView中的一些属性进行了操作。
    image
image
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 503 7672 好喝不贵,适口为珍。
    灵静自远阅读 203评论 0 0
  • 我连做梦也感觉受伤 一年过了 还是一天 计算着慌张 计程车上的音响 我们最爱的情歌 这一刻却重重击破思念的 心脏 ...
    MrairC阅读 244评论 0 0
  • 今天早上她推开门,满目刺眼的白让她吃了一惊,雪很厚,踩上去发出咯吱咯吱的声音,堪与老家的大雪相当。 不远处,花坛划...
    指尖上的独角兽阅读 602评论 0 1
  • 《一出好戏》上映了,这部黄渤执导的电影,前期宣传到位,各大综艺,以及黄渤等人自带人品,这部电影未播已经先火...
    SL_28f6阅读 202评论 2 2