iOS开发设计模式篇第一篇MVC设计模式

news2024/11/15 4:41:32

目录

1. 引言

2.概念

1.Model

1.职责

2.实现

3.和Controller通信        

1.Contrller直接访问Model

2.通过委托(Delegate)模式

3.通知

   4.KVO

4.设计的建议

2.View

1.职责

2.实现

3.和Controller通信

1. 目标-动作(Target-Action)模式

2. 委托(Delegate)模式

3. 通知(Notification)模式

4. KVC 和 KVO(Key-Value Coding 和 Key-Value Observing)

5. Block 回调

3.Controller

1.职责

2.实现

3.通信

3. MVC设计模式的优缺点

1.优点

2. 缺点

4. 实践中的建议


1. 引言

        MVC(Model-View-Controller)是一种常见的软件设计模式,旨在将应用程序的逻辑、用户界面和输入进行分离。

        在iOS开发中,MVC帮助开发者组织代码,提高可维护性和可扩展性,使得项目结构更加清晰。
        本文将介绍MVC的基本概念、在iOS中的具体实现、优缺点、实践建议,以及其他常见的架构模式。

2.概念

          MVC的全称和基本概念:MVC即Model-View-Controller,分别代表模型、视图和控制器三个部分。

        各个组件的职责:

  1. Model:负责数据和业务逻辑,包括数据的获取、保存、处理等。
  2. View:负责用户界面的展示,直接与用户进行交互。
  3. Controller:负责协调Model和View,处理用户输入,并将其转化为对Model的操作或View的更新。

        在我们面试的过程中,MVC基本上是面试必问的基础性的问题。笔者总结了两点:MVC就是Controller拿Model的数据区更新View,同时Model和View之间是不互相通信的,它们之间的联系是通过Controller来桥接。

        下图是斯坦福大学网上iOS公开课中的关于MVC的讲解,感觉总结的非常不错。

        图1.MVC设计模式图

        下面逐个分析下MVC中的每一个模块。

1.Model

        Model是数据模型的意思,在iOS的设计模式中,主要负责处理数据和业务逻辑。

1.职责

        Model的主要职责如下:

        1.数据存储:Model负责存储应用程序的数据。数据可以来自本地存储、网络请求或其他外部数据源。

        2.数据操作:Model包含操作数据的方法,例如创建、读取、更新和删除(CRUD)操作。

        3.业务逻辑:Model还负责处理应用程序的业务逻辑,例如数据验证、计算和转换等。

        4.数据通知:当数据发生变化时,Model可以通过通知或回调机制通知Controller,以便更新视图。

2.实现

        在实际的开发过程中,Model通常是一个或者多个类,这些类可以代表数据库中的表、网络请求的响应或其他数据结构

        下面是一个简单的Model类示例,演示了如何定义和操作Model:

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

@interface User : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;

- (instancetype)initWithName:(NSString *)name age:(NSInteger)age;
- (void)updateName:(NSString *)newName;
@end

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

@implementation User

- (instancetype)initWithName:(NSString *)name age:(NSInteger)age {
    self = [super init];
    if (self) {
        _name = name;
        _age = age;
    }
    return self;
}

- (void)updateName:(NSString *)newName {
    _name = newName;
    // 通知Controller数据已更新
    [[NSNotificationCenter defaultCenter] postNotificationName:@"UserUpdatedNotification" object:self];
}

@end

        在这个示例中,User类是一个简单的Model类,包含用户的姓名和年龄。它还提供了一个方法来更新用户的姓名,并在更新后通过通知机制通知Controller。

3.和Controller通信        

        Model通常不会直接与View通信,而是通过Controller进行中介。Controller负责监听Model的数据变化,并相应地更新View。

        Model和Controller中的通信方式有以下几种方式:

1.Contrller直接访问Model

        Controller可以直接访问model的属性和方法。

        Controller可以直接访问和操作Model的属性和方法,以获取或更新数据。这是最直接和常见的方式。

        我们以下面的更新App版本号为例:

        图1.更新app版本号

         因为Controller直接持有Model,因此我们直接可以直接修改model数据:

#pragma mark -- AboutViewDelegate

- (void)didTapUpdateButton{

    self.aboutModel.appVersion = [NSString stringWithFormat:@"%ld.%ld.%ld",[self generateRandomNumber:10],[self generateRandomNumber:99],[self generateRandomNumber:99]];

    [self.aboutView configureWithModel:self.aboutModel];

}

- (NSInteger)generateRandomNumber:(NSInteger)random {

    return arc4random_uniform(10) + 1; // 生成1到10之间的随机数

}

        完整代码如下:

#import "AboutViewController.h"
#import "AboutView.h"
#import "AboutModel.h"
#import "Masonry.h"

@interface AboutViewController ()<AboutViewDelegate>

@property (nonatomic, strong) AboutView *aboutView;
@property (nonatomic, strong) AboutModel *aboutModel;

@end

@implementation AboutViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    self.title = @"关于";
    [self setupModel];
    [self setupView];
}

- (void)setupModel {
    // 假设我们从某处获取了应用的名称和版本号
    NSString *appName = @"myApp";
    NSString *appVersion = @"1.0.0";
    
    self.aboutModel = [[AboutModel alloc] initWithAppName:appName appVersion:appVersion];
}

- (void)setupView {
    self.aboutView = [[AboutView alloc] initWithFrame:self.view.bounds];
    self.aboutView.delegate = self;
    [self.view addSubview:self.aboutView];
    
    [self.aboutView configureWithModel:self.aboutModel];
}

#pragma mark -- AboutViewDelegate
- (void)didTapUpdateButton{
    self.aboutModel.appVersion = [NSString stringWithFormat:@"%ld.%ld.%ld",[self generateRandomNumber:10],[self generateRandomNumber:99],[self generateRandomNumber:99]];
    [self.aboutView configureWithModel:self.aboutModel];

}
- (NSInteger)generateRandomNumber:(NSInteger)random {
    return arc4random_uniform(10) + 1; // 生成1到10之间的随机数
}
@end
2.通过委托(Delegate)模式

        Model可以定义一个协议(protocol),Controller遵循这个协议并实现其方法。Model通过委托将数据变化通知给Controller,Controller则通过协议的方法来响应这些变化。

        还以上面的demo为例,我们还可以把更新的方法传递到Controller,让controller去处理。

#import "AboutViewController.h"
#import "AboutView.h"
#import "AboutModel.h"
#import "Masonry.h"

@interface AboutViewController ()<AboutViewDelegate,AboutModelDelegate>

@property (nonatomic, strong) AboutView *aboutView;
@property (nonatomic, strong) AboutModel *aboutModel;

@end

@implementation AboutViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    self.title = @"关于";
    [self setupModel];
    [self setupView];
}

- (void)setupModel {
    // 假设我们从某处获取了应用的名称和版本号
    NSString *appName = @"myApp";
    NSString *appVersion = @"1.0.0";
    
    self.aboutModel = [[AboutModel alloc] initWithAppName:appName appVersion:appVersion];
    self.aboutModel.delegate = self;
}

- (void)setupView {
    self.aboutView = [[AboutView alloc] initWithFrame:self.view.bounds];
    self.aboutView.delegate = self;
    [self.view addSubview:self.aboutView];
    
    [self.aboutView configureWithModel:self.aboutModel];
}

#pragma mark -- AboutViewDelegate
- (void)didTapUpdateButton{
    NSLog(@"didTapUpdateButton");
    [self.aboutModel updateAppVersion:[NSString stringWithFormat:@"%ld.%ld.%ld",[self generateRandomNumber:10],[self generateRandomNumber:99],[self generateRandomNumber:99]]];

}
#pragma mark -- AboutModelDelegate
- (void)didUpdateAppVersion:(NSString *)appVersion{
    NSLog(@"AboutModelDelegate");
    [self.aboutView configureWithModel:self.aboutModel];
}

- (NSInteger)generateRandomNumber:(NSInteger)random {
    return arc4random_uniform(10) + 1; // 生成1到10之间的随机数
}
@end
3.通知

        iOS的通知机制(NSNotificationCenter)允许在应用程序的不同部分之间发送消息。Controller可以监听特定的通知,以便在Model发出通知时执行相应的操作。

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

@interface MyModel : NSObject
@property (nonatomic, strong) NSString *data;

- (void)updateData:(NSString *)newData;
@end

// MyModel.m
#import "MyModel.h"

@implementation MyModel

- (void)updateData:(NSString *)newData {
    _data = newData;
    [[NSNotificationCenter defaultCenter] postNotificationName:@"DataUpdatedNotification" object:newData];
}

@end

// MyViewController.m
#import "MyViewController.h"
#import "MyModel.h"

@implementation MyViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.myModel = [[MyModel alloc] init];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDataUpdated:) name:@"DataUpdatedNotification" object:nil];
    
    [self.myModel updateData:@"New Data"];
}

- (void)handleDataUpdated:(NSNotification *)notification {
    NSString *updatedData = (NSString *)notification.object;
    NSLog(@"Model data updated: %@", updatedData);
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

@end
   4.KVO

        KVO是一种观察模式,允许对象监听其他对象属性的变化。Controller可以监听Model的属性变化,以便在属性发生变化时进行相应的处理。

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

@interface MyModel : NSObject
@property (nonatomic, strong) NSString *data;
@end

// MyModel.m
#import "MyModel.h"

@implementation MyModel

- (instancetype)init {
    self = [super init];
    if (self) {
        _data = @"Hello, MVC!";
    }
    return self;
}

@end

// MyViewController.m
#import "MyViewController.h"
#import "MyModel.h"

@implementation MyViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.myModel = [[MyModel alloc] init];
    [self.myModel addObserver:self forKeyPath:@"data" options:NSKeyValueObservingOptionNew context:nil];
    
    self.myModel.data = @"Updated Data";
}

// 处理属性变化
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"data"]) {
        NSLog(@"Model data changed: %@", change[NSKeyValueChangeNewKey]);
    }
}

- (void)dealloc {
    [self.myModel removeObserver:self forKeyPath:@"data"];
}

@end

4.设计的建议

  1. 保持Model的独立性:Model不应该直接依赖View或Controller。这样可以使Model更加独立和可复用。
  2. 使用协议和委托:可以使用协议和委托来定义Model与Controller的交互接口,增强代码的灵活性和可维护性。
  3. 使用数据持久化框架:在处理复杂数据模型时,可以使用Core Data、Realm等数据持久化框架来简化数据管理和存储。
  4. 注意线程安全:在多线程环境下操作Model时,需要注意线程安全,避免数据竞争和不一致问题。

2.View

1.职责

        view是视图的意思。在iOS MVC(Model-View-Controller)设计模式中,View 负责管理应用程序的用户界面(UI)部分。它是用户与应用程序进行交互的界面层,负责显示数据和响应用户操作。以下是对 View 的详细介绍:

  1. 展示数据:View 负责根据 Model 提供的数据来展示用户界面。它不直接处理数据的逻辑,只是按照 Controller 提供的数据进行展示。View 的任务是将数据直观地呈现给用户。
  2. 相应用户输入:View 负责处理用户的输入,如点击按钮、滑动屏幕等操作,并将这些事件传递给 Controller 进行处理。View 本身不包含业务逻辑,而是将事件传递给负责逻辑处理的 Controller。
  3. 独立于业务逻辑:View 不应包含应用程序的业务逻辑或数据处理逻辑。它与 Model 之间没有直接的交互,所有的数据交互都通过 Controller 来完成。这种独立性使得 View 可以很容易地进行修改或替换,而不会影响到应用程序的其他部分。           
2.实现

        在 iOS 应用程序中,View 的典型组件包括:UIView、UILabel、UIButton、UIImageView、UITableView等。

3.和Controller通信

1. 目标-动作(Target-Action)模式

        目标-动作模式是 iOS 中常用的一种通信方式,通常用于处理用户界面控件(如按钮、开关、滑块等)的事件。当用户与控件交互时,控件会向其指定的目标(通常是 Controller)发送一个动作消息。

// 在View中设置目标和动作
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
[button setTitle:@"Press Me" forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];

// Controller 中实现动作方法
- (void)buttonPressed:(UIButton *)sender {
    NSLog(@"Button was pressed");
}

2. 委托(Delegate)模式

        托模式是一种常见的设计模式,允许一个对象向另一个对象通知发生的事件。在 iOS 中,许多 UIKit 组件都使用委托模式,例如 UITableView 和 UICollectionView。Controller 通常会作为 View 的委托对象,以便处理 View 的事件。

// 自定义View中的委托协议
@protocol CustomViewDelegate <NSObject>
- (void)customViewDidSomething:(UIView *)view;
@end

@interface CustomView : UIView
@property (nonatomic, weak) id<CustomViewDelegate> delegate;
@end

@implementation CustomView
- (void)doSomething {
    [self.delegate customViewDidSomething:self];
}
@end

// 在Controller中实现委托方法
@interface ViewController () <CustomViewDelegate>
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    
    CustomView *customView = [[CustomView alloc] init];
    customView.delegate = self;
    [self.view addSubview:customView];
}

- (void)customViewDidSomething:(UIView *)view {
    NSLog(@"CustomView did something");
}
@end

3. 通知(Notification)模式

        通知中心(NSNotificationCenter)是一种广播机制,允许对象通过发布和观察通知进行通信。通知是一对多的通信机制,适用于需要向多个对象广播信息的情况。

// 发送通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"CustomNotification" object:nil];

// 观察通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:@"CustomNotification" object:nil];

// 处理通知的方法
- (void)handleNotification:(NSNotification *)notification {
    NSLog(@"Received CustomNotification");
}

// 移除观察者
- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

4. KVC 和 KVO(Key-Value Coding 和 Key-Value Observing)

        KVC 和 KVO 是 Cocoa 提供的动态属性访问和观察机制。KVC 允许通过字符串键来访问对象的属性,KVO 允许对象观察其他对象属性的变化。

// Model类
@interface Person : NSObject
@property (nonatomic, strong) NSString *name;
@end

@implementation Person
@end

// Controller中使用KVO观察属性变化
@interface ViewController ()
@property (nonatomic, strong) Person *person;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.person = [[Person alloc] init];
    [self.person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
}

// 实现观察者方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"name"]) {
        NSLog(@"Person's name changed to %@", change[NSKeyValueChangeNewKey]);
    }
}

// 移除观察者
- (void)dealloc {
    [self.person removeObserver:self forKeyPath:@"name"];
}
@end

5. Block 回调

        Block 回调是一种轻量级的替代委托模式的方法。它允许在执行某些操作后,调用一个代码块(block)来处理结果。Block 回调简化了委托模式,不需要定义协议和委托对象。

// 自定义View类使用Block回调
@interface CustomView : UIView
@property (nonatomic, copy) void (^buttonPressedBlock)(void);
@end

@implementation CustomView
- (instancetype)init {
    self = [super init];
    if (self) {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
        [button setTitle:@"Press Me" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:button];
    }
    return self;
}

- (void)buttonPressed {
    if (self.buttonPressedBlock) {
        self.buttonPressedBlock();
    }
}
@end

// 在Controller中设置Block回调
@interface ViewController ()
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    
    CustomView *customView = [[CustomView alloc] init];
    customView.buttonPressedBlock = ^{
        NSLog(@"Button was pressed in CustomView");
    };
    [self.view addSubview:customView];
}
@end

3.Controller

1.职责

        在 iOS 的 MVC(Model-View-Controller)设计模式中,Controller 是连接 Model 和 View 的中介,负责处理应用程序的业务逻辑和用户交互。Controller 的主要职责是从 Model 中获取数据,更新 View,并响应用户输入。以下是对 Controller 的详细介绍:

        1.管理视图:

                Controller 负责创建和配置 View,并将 Model 中的数据传递给 View 进行显示。当 Model 的数据发生变化时,Controller 也会通知 View 进行相应的更新。

        2.处理用户输入:

                Controller 响应用户在 View 上的各种操作,例如点击按钮、滑动手势等。它会根据用户的输入更新 Model,并通过 View 来反映这些变化。

        3.业务逻辑:

                Controller 包含应用程序的业务逻辑和数据处理逻辑。它从 Model 获取数据、处理数据,并将处理结果传递给 View。

        3.中介作用:

                Controller 充当 Model 和 View 之间的中介。它负责协调这两者之间的通信,使得 View 不直接与 Model 交互,从而保持两者的解耦。

2.实现

        在 iOS 开发中,UIViewController 是 Controller 的基类。每个 UIViewController 都管理一个 UIView,并与该视图相关联的 Model 进行交互。

3.通信

        Controller和Model以及View之间的通信可以看上面的章节。

3. MVC设计模式的优缺点

1.优点

        1.易于测试和维护

                各个组件独立,便于单独测试和维护。

        2.代码复用性强

                View和Model可以在不同的Controller中重复使用,提高代码复用性。

2. 缺点

        1.可能导致Controller过于臃肿

                在处理复杂逻辑时,Controller可能变得过于庞大,难以维护。
         2.View和Controller之间的耦合度较

                由于Controller直接管理View,导致二者耦合度较高,不利于独立开发和测试。
          3.复杂项目中的可扩展性问题

                在大型项目中,MVC可能难以满足复杂需求,需要引入其他设计模式进行补充。

4. 实践中的建议

1.如何避免Controller臃肿

        使用Helper类或Extensions分担部分逻辑。

        将业务逻辑移到Model层,尽量保持Controller的简洁。
2.减少View和Controller的耦合

         使用协议和委托模式来解耦。

         利用通知和KVO(Key-Value Observing)机制实现低耦合的数据传递。
3.代码组织和文件结构的最佳实践:

        将Model、View、Controller分别放在不同的文件夹中。

        使用命名空间或模块化方式组织代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1942898.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

matlab gui下的tcp client客户端编程框架

GUI界面 函数外定义全局变量 %全局变量 global TcpClient; %matlab作为tcpip客户端 建立连接 在“连接”按钮的回调函数下添加以下代码&#xff1a; global TcpClient;%全局变量 TcpClient tcpip(‘192.168.1.10’, 7, ‘NetworkRole’,‘client’); %连接到服务器地址和端…

免费【2024】springboot北京医疗企业固定资产管理系统的设计与实现

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

Springboot项目打包成镜像、使用docker-compose启动

Springboot项目打包成镜像、使用docker-compose启动 1、创建一个boot项目 1、添加依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSch…

Adobe Dimension(DN)安装包软件下载

目录 一、软件简介 二、软件下载 三、注意事项 四、软件功能 五、常用快捷键 快捷键&#xff1a; 一、软件简介 Adobe Dimension&#xff08;简称DN&#xff09;是Adobe公司推出的一款三维设计和渲染软件。与一般的3D绘图软件相比&#xff0c;DN在操作界面和功能上有所不…

预防大于治疗!夏季脑血管疾病高发,应该注意什么?

夏日炎炎&#xff0c;虽然气温攀升带来了一抹活力&#xff0c;却也悄悄增加了心脑血管疾病的风险。高温、高湿的环境易使人体血管扩张&#xff0c;心率加快&#xff0c;血液黏稠度上升&#xff0c;对于中老年人及已有心脑血管疾病史的人群而言&#xff0c;更是需要格外警惕。因…

项目实战--C#实现图书馆信息管理系统

本项目是要开发一个图书馆管理系统&#xff0c;通过这个系统处理常见的图书馆业务。这个系统主要功能是&#xff1a;&#xff08;1&#xff09;有客户端&#xff08;借阅者使用&#xff09;和管理端&#xff08;图书馆管理员和系统管理员使用&#xff09;。&#xff08;2&#…

Cxx Primer-chap6

什么是函数&#xff1a;A function is a block of code with a name.&#xff1a;函数调用和返回&#xff1a;&#xff0c;实例&#xff1a;名字有作用域(visible)&#xff0c;对象有生命周期(exist)&#xff1a; &#xff0c;lifetime取决于object在哪定义和如何定义&#xff…

算法题目整合4

文章目录 122. 大数减法123. 滑动窗口最大值117. 软件构建124. 小红的数组构造125. 精华帖子126. 连续子数组最大和 122. 大数减法 题目描述 以字符串的形式读入两个数字&#xff0c;编写一个函数计算它们的差&#xff0c;以字符串形式返回。输入描述 输入两个数字&#xff…

FPGA DNA 获取 DNA_PORT

FPGA DNA DNA 是 FPGA 芯片的唯一标识&#xff0c; FPGA 都有一个独特的 ID &#xff0c;也就是 Device DNA &#xff0c;这个 ID 相当于我们的身份证&#xff0c;在 FPGA 芯片生产的时候就已经固定在芯片的 eFuse 寄存器中&#xff0c;具有不可修改的属性。在 xilinx 7series…

Adobe国际认证详解-职业发展规划指南

Adobe国际认证&#xff0c;又称为Adobe Certified Professional&#xff08;简称ACP&#xff09;&#xff0c;是Adobe公司CEO签发的权威国际认证体系。这一认证体系基于Adobe核心技术及岗位实际应用操作能力的测评&#xff0c;旨在为用户提供创意软件的专业认证。 Adobe国际认证…

win11 安装 Gradle以及通过Gradle 编译Spring boot 2.7.x源码

一、win11 安装Gradle(7.5.1)&#xff1a; 1.1、下载二进制包 Gradle下载页面 1.2、配置环境变量 变量名&#xff1a;GRADLE_HOME 变量值&#xff08;二进制包解压路径&#xff09;&#xff1a;D:\develop-tool\gradle-7.5.1 变量名&#xff1a;GRADLE_USER_HOME 变量值&a…

知识表示 | 利用 Protégé 软件构建小型本体

Hi&#xff0c;大家好&#xff0c;我是半亩花海。本项目旨在利用 Protg 软件构建小型本体&#xff0c;探索本体建模的实际应用&#xff0c;特别是应用本体与上层本体之间的关系继承与映射。我们将重点理解应用本体如何继承上层本体的关系&#xff0c;以及如何通过推理机制揭示实…

线性dp.

线性dp&#xff0c;在进行动态规划中&#xff0c;常以线性的形式表现出来。 我们仍用闫氏dp法来进行求解即可 一、状态表示&#xff1a;当前的状态所代表的含义以及能用几维的形式表现出来。包括①集合&#xff0c;②属性 二、状态计算&#xff1a;如何一步一步的将状态计算出…

Hostspot2.0网络是什么?

Hotspot 2.0是一种无线网络技术标准&#xff0c;它是由Wi-Fi联盟推出的&#xff0c;旨在改善公共Wi-Fi热点的用户体验&#xff0c;简化连接流程&#xff0c;提升安全性&#xff0c;并提供更好的漫游体验。Hotspot 2.0也被称为Passpoint&#xff08;Passpoint Release 2&#xf…

Go基础编程 - 12 -流程控制

流程控制 1. 条件语句1.1. if...else 语句1.2. switch 语句1.3. select 语句1.3.1. select 语句的通信表达式1.3.2. select 的基特性1.3.3. select 的实现原理1.3.4. 经典用法1.3.4.1 超时控制1.3.4.2 多任务并发控制1.3.4.3 监听多通道消息1.3.4.4 default 实现非堵塞读写 2. …

【全网首发】小红书最新引流法:轻松留联系方式卡片,直接上演无举报窗口

大家好&#xff01;我是闷声轻创&#xff01;根据最新消息小红书卡片可能会被禁止掉&#xff0c;这对我们的引流矩阵有真不小的冲击&#xff0c;毕竟小红书作为国内领​先的年轻人的生活分享社区&#xff0c;但上有政策下有对策&#xff0c;我今天发现了一个新的留V的方法&…

七天打造一套量化交易系统:Day2-量化交易策略基本模型及要点

七天打造一套量化交易系统&#xff1a;Day2-量化交易策略基本模型及要点 前期回顾趋势型策略模型原理收益分布重点&#xff1a;什么因素能改进策略&#xff08;截断亏损&#xff0c;让利润奔跑&#xff09;要点总结 均值回复型策略模型原理收益分布重点&#xff1a;避免大额亏损…

去掉roscore的python依赖概述

去掉roscore的python依赖概述 文章目录 去掉roscore的python依赖概述roscore有哪些功能思路关于rosmaster本身及其API的介绍 需要实现的核心API代码实现附录(网图) roscore有哪些功能 启动一个rosmaster节点 调用roslaunch在子进程中&#xff08;popen&#xff09;启动rosmast…

浪潮自研交换机系列常见问题处理

CN61108PC-V-H 不能PING通任何地址&#xff0c;也不能被PING 输入ip traceroute enable既可。注意视图 交换机通过console口远程登录至其他交换机&#xff0c;掉线后console口无法使用 例如有2台交换机A和B&#xff0c;在A交换机上插上console线登录后&#xff0c;在A通过SSH…

【入门教程一】基于DE2-115的My First FPGA 工程

1.1. 概述 这是一个简单的练习&#xff0c; 可以帮助初学者开始了解如何使用Intel Quartus 软件进行 FPGA 开发。 在本章节中&#xff0c;您将学习如何编译 Verilog 代码&#xff0c;进行引脚分配&#xff0c;创建时序约束&#xff0c;然后对 FPGA 进行编程&#xff0c;驱动开…