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中的一些属性进行了操作。