IOS入门-扩展语法

类目

类目就可以实现在没有类的源代码的条件下为类增加新的方法

扩展NSString的.h头文件

//  NSString+GetName.h
//  类目
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface NSString (GetName)
//@property(nonatomic,strong)NSString *sex;不可以给类别/类目添加属性

- (NSString *)getName;

- (NSInteger)getAge;

@end

NS_ASSUME_NONNULL_END

扩展NSString的.m实现文件

//  NSString+GetName.m
//  类目
#import "NSString+GetName.h"

@implementation NSString (GetName)

- (NSString *)getName{
    return @"张三";
}

- (NSInteger)getAge{
    return 23;
}
@end

使用

//
//  ViewController.m
//  类目
#import "ViewController.h"
#import "NSString+GetName.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    NSstring *str=[[NSString alloc]init];
    NSString *name=[str getName];
    NSString *age=[str getAge];
    NSLog(@"name = %@  age = %d",name,age);
}
@end

延展

为类扩充私有的方法,以及私有的实例变量

延展.h头文件

//  User.h
//  延展
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface User : NSObject

@property(nonatomic,strong)NSString *name;

- (void)getName;

@end

NS_ASSUME_NONNULL_END

延展.m实现文件

//
//  User.m
//  延展

#import "User.h"

@interface User ()
//延展的属性,私有
@property(nonatomic,assign)NSInteger age;

- (void)setAge;

@end

@implementation User

- (void)setAge{
    self.age=12;
}

- (void) getAge{
    [self setAge];
    NSLog(@"self.age = %ld",(long)self.age);
}
@end

协议,代理

一个类只要遵守了Protocol协议,就相当于拥有了Protocol协议的所有方法声明,类似于java中接口

协议.h头文件

//  Person.h
//  协议

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN
//协议
@protocol Person<NSObject>
//@required关键字之后声明的方法必选实现
@required
- (void)driveCar;
//@optional关键字之后声明的方法可选实现
@optional
- (void)buyCar;
@end

NS_ASSUME_NONNULL_END

继承协议的.h头文件

//  Worker.h
//  协议

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

NS_ASSUME_NONNULL_BEGIN
@interface Worker: NSObject<Person>
@property(nonatomic,weak)id<Person> delegate;
@end

NS_ASSUME_NONNULL_END

实现协议的.m文件

//  Worker.m
//  协议
#import "Worker.h"

@implementation Worker

- (void)driveCar{
    NSLog(@"工作人员开车"):
}
@end

代理.h头文件

//
//  Saleman.h
//  协议
#import <Foundation/Foundation.h>
#import "Person.h"

NS_ASSUME_NONNULL_BEGIN

@interface Saleman : NSObject<Person>

@end

NS_ASSUME_NONNULL_END

代理.m实现文件

//
//  Saleman.m
//  协议
#import "Saleman.h"

@implementation Saleman

- (void)driveCar{
    NSLog(@"销售人员开车");
}
- (void)buyCar{
    NSLog(@"销售人员买车");
}
@end

使用

#import "ViewController.h"
#import "Worker.h"
#import "Saleman.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    Worker*worker= [[Worker alloc]init];
    
    Saleman*saleman= [[Saleman alloc]init];
    //协议是协议  代理是代理
    worker.delegate = saleman;//saleman成为了worker的代理
    //判断代理是否有此方法
    if ([worker.delegate respondsToSelector:@selector(buyCar)]) {
        [worker.delegate buyCar];
    }
    
}


@end

KVO

key-value-observer表示当某个属性的值发生变化的时候,通知观察者

编写实体.h头文件

//
//  User.h
//  KVO
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface User: NSObject

@property(nonatomic,strong)NSString *name;

@property(nonatomic,assign)NSInteger age;

@end

NS_ASSUME_NONNULL_END

实现实体.m文件

//  User.h
//  KVO
#import "User.h"

@implementation User

@end

使用

//  ViewController.m
//  KVO

#import "ViewController.h"
#import "Persion.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    User *user= [[User alloc]init];
    
    [user addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
    [user addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew context:nil];
    user.name = @"张三";
    
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    id value = change[NSKeyValueChangeNewKey];
    
    if ([keyPath isEqualToString:@"name"]) {
        NSLog(@"name= %@",value);
    }else if([keyPath isEqualToString:@"age"]){
         NSLog(@"age= %d",value);
    }
}


@end

KVC

Key Value Coding(键值编码),是一个基于NSKeyValueCoding非正式协议实现的机制,它可以直接通过key值对对象的属性进行存取操作,而不需通过调用明确的存取方法。这样就可以在运行时动态再访问和修改对象的属性,而不是在编译时确定

实体类.h头文件

//
//  Address.h
//  KVC
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Address : NSObject

@property(nonatomic,strong)NSString *city;

@property(nonatomic,strong)NSString *street;

@end

NS_ASSUME_NONNULL_END

实体类.h头文件

//
//  //
//  Persion.h
//  KVC

#import <Foundation/Foundation.h>
#import "Address.h"

NS_ASSUME_NONNULL_BEGIN

@interface User: NSObject

@property(nonatomic,strong)NSString *name;

@property(nonatomic,assign)NSInteger age;

@property(nonatomic,strong)Address *address;

@end

NS_ASSUME_NONNULL_END

使用

//  ViewController.m
//  KVC
#import "ViewController.h"
#import "User.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //kvc的目的是不通过属性,去赋值和取值
    User *user= [[Persion alloc]init];
    //利用KVC
    //赋值
    [user setValue:@"张三" forKey:@"name"];
    //取值
//    NSLog(@"user.name2 = %@",[user valueForKey:@"name"]);
    
    Address *address = [[Address alloc]init];
//    [address setValue:@"wuhu" forKey:@"city"];
//    user.address = address;
    [persion setValue:address forKey:@"address"];
    
    //多级访问(访问user里面的address里面的city) //多级访问一定是keypath
    [user setValue:@"wuhu" forKeyPath:@"address.city"];
    
//    NSLog(@"city = %@",user.address.city);//属性get方法访问
    NSLog(@"city01 = %@",[uservalueForKeyPath:@"address.city"]);
}


@end

单例

在整个程序中只有一个实例,并且提供一个类方法供全局调用,在编译时初始化这个类,然后一直保存在内存中,到程序(APP)退出时由系统自动释放这部分内存。

实体类.h头文件

//  User.h
//  OC单例

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface User: NSObject

+ (User *)shareInstance;

@end

NS_ASSUME_NONNULL_END

实体类.m实现文件

//  Persion.m
//  OC单例
#import "User.h"

@implementation User

static User *_user;

+(instancetype)allocWithZone:(struct _NSZone *)zone{
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (_user == nil) {
            _user = [super allocWithZone:zone];
        }
    });
    
    return _user;
}

+ (User *)shareInstance{
    return [[self alloc]init];
}

- (id)copyWithZone:(NSZone *)zone{
    return _user;
}

- (id)mutableCopyWithZone:(NSZone*)zone{
    return _user;
}

@end

通知

一种消息广播的实现机制,可以在不同对象之间发送通知进而实现通信

1、发送通知
    [[NSNotificationCenter defaultCenter] postNotificationName:@"notice" object:nil];

2、向通知中心注册通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(action:) name:@"notice" object:nil];

3、接收通知
action: 是响应接收通知的方法,在收到通知后会调用此方法。name是这个通知的名字。

- (void)action:(NSNotification*)notif
{
    NSLog(@"接收到的消息 %@",notif.object);
}

4、销毁通知
在需要销毁的时候,可以根据通知的名字remove-(void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"notice" object:nil];
}

目标动作回调

事件发生时,向指定的对象发送某个特定的信息。这里接收消息的对象是目标,消息的选择器是动作。常用为按钮addTarget属性 ;

//  ViewController.m
//  目标动作回调
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //目标动作回调
    //目标就是接受事件反馈的对象
    //动作:事件反馈所要触发的方法
    
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button addTarget:self action:@selector(click) 	forControlEvents:UIControlEventTouchUpInside];
    button.frame = CGRectMake(0, 100, 100, 100);
    [self.view addSubview:button];
    button.backgroundColor = [UIColor redColor];
    [button setTitle:@"按钮" forState:UIControlStateNormal];
}
- (void)click{
    NSLog(@"我被触发了");
}


@end

委托协议回调

事件发生时,向指定的对象发送某个特定的信息。这里接收消息的对象是目标,消息的选择器是动作。常用为按钮addTarget属性 ;

闹铃协议.h头文件

//  Alarm.h
//  委托模式

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@protocol Alarm<NSObject>

- (void)ringing;

@end

NS_ASSUME_NONNULL_END

闹钟遵从闹铃协议.h头文件

//
//  Clock.h
//  委托模式

#import <Foundation/Foundation.h>
#import "Alarm.h"

NS_ASSUME_NONNULL_BEGIN

@interface Clock : NSObject<Alarm>

@end

NS_ASSUME_NONNULL_END

闹钟遵从闹铃协议.m实现文件

//  Clock.m
//  委托模式
#import "Clock.h"

@implementation Clock

- (void)ringing{
    NSLog(@"叮叮叮。。");
}
@end

将闹钟设为人的代理.h头文件

//  Person.h
//  委托模式
#import <Foundation/Foundation.h>
#import "Alarm.h"

NS_ASSUME_NONNULL_BEGIN

@interface Person: NSObject

@property(nonatomic,weak)id<Alarm>delegate;

@end

NS_ASSUME_NONNULL_END

使用

//  ViewController.m
//  委托模式
#import "ViewController.h"
#import "Person.h"
#import "Clock.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    Person*person= [[Personalloc]init];
    
    Clock *clock = [[Clock alloc]init];
    person.delegate = clock;
    
    [person.delegate ring];
}

@end

Block回调

子控件TestView.h头文件

//  TestView.h
//  回调Block
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

typedef void(^TestBlock)(NSString *str);

@interface TestView : UIView
//视图
@property(nonatomic,strong)void(^changeColor)(NSString *test);
@property(nonatomic,strong)TestBlock testBlock;

//block作为函数的参数
//- (void)userBlock:(void(^)(NSString *str))block;

- (void)userBlock:(TestBlock)testBlock;
@property(nonatomic,strong)void(^changeValueBlock)(void);
@end

NS_ASSUME_NONNULL_END

子控件TestView.m实现文件

//  TestView.m
//  回调Block
#import "TestView.h"

@implementation TestView

- (instancetype)init
{
    self = [super init];
    if (self) {
        
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.backgroundColor=[UIColor redColor];
        [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [button setTitle:@"点我" forState:UIControlStateNormal];
        button.titleLabel.font = [UIFont systemFontOfSize:18];
        button.frame = CGRectMake(0, 0, 300, 50);
        
        [self addSubview:button];
        
    }
    return self;
}

- (void)buttonAction:(UIButton *)sender{
    NSLog(@"触发");
    self.changeColor(@"函数传过来的参数");    
    if (self.changeValueBlock) {
        self.changeValueBlock();
    }
    
}

//- (void)userBlock:(void(^)(NSString *str))block{
//    self.changeColor = block;
//}

- (void)userBlock:(TestBlock)testBlock{
    self.changeColor = testBlock;
}

@end

使用

//  ViewController.m
//  回调Block
#import "ViewController.h"
#import "TestView.h"
#import "FirstViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //block
    /*
     代码块Block是苹果在iOS4开始引入的对C语言的扩展,用来实现匿名函数的特性,Block是一种特殊的数据类型,其可以正常定义变量、作为参数、作为返回值;Block被广泛运用在回调。
     
     注: Block的声明与赋值只是保存了一段代码段,必须调用才能执行内部代码.
     */
    
    TestView *view = [[TestView alloc]init];
    view.frame = CGRectMake(self.view.frame.size.width/2.0 - 150, 300, 300, 50);
    [self.view addSubview: view];
    view.changeColor = ^(NSString * _Nonnull test) {
        NSLog(@"test = %@",test);
    };
    
//    [view userBlock:^(NSString * _Nonnull str) {
//        NSLog(@"str = %@",str);
//        self.view.backgroundColor = [UIColor greenColor];
//    }];
    
    [view userBlock:^(NSString * _Nonnull str) {
        NSLog(@"str = %@",str);
        self.view.backgroundColor = [UIColor greenColor];

    }];
   
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.backgroundColor=[UIColor redColor];
    [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
    [button setTitle:@"按钮1" forState:UIControlStateNormal];
    button.titleLabel.font = [UIFont systemFontOfSize:18];
    button.frame = CGRectMake(0, 100, 300, 50);
    
    [self.view addSubview:button];
    
}

- (void)buttonAction:(UIButton *)sender{
    NSLog(@"按钮1事件");
//    self.view.backgroundColor = [UIColor yellowColor];
    FirstViewController *firstViewControlelr = [[FirstViewController alloc]init];
    [self presentViewController:firstViewControlelr animated:YES completion:^{
        
    }];
    
    
}


@end

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值