KVO (Key-Value Observing) 是 Cocoa 中公认的最强大的特性之一,但是同时它也以烂到家的 API 和极其难用著称。和属性观察不同,KVO 的目的并不是为当前类的属性提供一个钩子方法,而是为了其他不同实例对当前的某个属性 (严格来说是 keypath) 进行监听时使用的。其他实例可以充当一个订阅者的角色,当被监听的属性发生变化时,订阅者将得到通知。
在 Swift 中我们也是可以使用 KVO 的,观察者和被观察者都必须是 NSObject 的子类。这是可以理解的,因为 KVO 是基于 KVC (Key-Value Coding) 以及动态派发技术实现的,而这些东西都是 Objective-C 运行时的概念,这也意味着 Swift 中强大的 Struct,Enum以及泛型都与 KVO 无缘了。另外由于 Swift 为了效率,默认禁用了动态派发,因此想用 Swift 来实现 KVO,我们还需要做额外的工作,那就是将想要观测的对象标记为 dynamic,表示该属性的存取都由 runtime 在运行时来决定。除此之外,在 NSObject 子类中几乎没有属性默认是使用@dynamic 修饰(该关键字最常见场景是在 Core Data 里, NSManagedObject 子类的属性都是 dynamic 的),所以若想对某个属性进行观察,还必须在当前的子类中 override 该属性,override 时,采用 super 的实现即可。
所以Swift要使用KVO必须满足:
- 观察者和被观察者都必须是 NSObject 的子类
- 监听属性必须标记dynamic
原理:
- 当某个类的对象第一次被观察时,系统就会在运行期动态地创建该类的一个派生类,在这个派生类中重写基类中任何被观察属性的 setter 方法。
- 派生类在被重写的 setter 方法实现真正的通知机制,键值观察通知依赖于 NSObject 的两个方法: willChangeValueForKey: 和 didChangevlueForKey: 。在一个被观察属性发生改变之前, willChangeValueForKey: 一定会被调用,这就 会记录旧的值。而当改变发生后, didChangeValueForKey: 会被调用,继而 observeValueForKey:ofObject:change:context: 也会被调用。可以手动实现这些调用,但很少有人这么做。这么做是基于设置属性会调用 setter 方法,而通过重写就获得了 KVO 需要的通知机制。当然前提是要通过遵循 KVO 的属性设置方式来变更属性值,如果仅是直接修改属性对应的成员变量,是无法实现 KVO 的。
- 同时派生类还重写了 class 方法以“欺骗”外部调用者它就是起初的那个类。
- 系统将这个对象的 isa 指针指向这个新诞生的派生类,因此这个对象就成为该派生类的对象了,因而在该对象上对 setter 的调用就会调用重写的 setter,从而激活键值通知机制。
- 派生类还重写了 dealloc 方法来释放资源。
看下面代码:
-----------------start------------
对象变量名字: people
对象: <TestKVOKVC.People: 0x7fa449c14a60>
类: TestKVOKVC.People
元类: TestKVOKVC.People
实现的方法: setAge:, setSex:, age, sex, initWithName:age:sex:address:, name, address, .cxx_destruct, init, setName:, setAddress:,
-----------------end------------
-----------------start------------
对象变量名字: namePeople
对象: <TestKVOKVC.People: 0x7fa449c61e20>
类: TestKVOKVC.People
元类: NSKVONotifying_TestKVOKVC.People
实现的方法: setAge:, setName:, class, dealloc, _isKVOA,
-----------------end------------
-----------------start------------
对象变量名字: nameAgePeople
对象: <TestKVOKVC.People: 0x7fa449cbe990>
类: TestKVOKVC.People
元类: NSKVONotifying_TestKVOKVC.People
实现的方法: setAge:, setName:, class, dealloc, _isKVOA,
-----------------end------------
0x00000001083a3c60
0x00000001089807fa
0x00000001083a3c60
0x00000001089807fa
可以看到输出类名始终为:TestKVOKVC.People,这是因为新诞生的派生类重写了 -class 方法声称它就是起初的基类,只有使用 runtime 函数 object_getClass 才能一睹芳容:NSKVONotifying_TestKVOKVC.People。注意看:name,age 两个被观察对象真正的类型都是 NSKVONotifying_TestKVOKVC.People,而且该类实现了:setAge:, setName:, class, dealloc, _isKVOA 这些方法。其中 setAge:, setName:重写实现通知机制, class声明原来的类 , dealloc释放资源,私有方法 _isKVOA 是用来标示该类是一个 KVO 机制声称的类。在这里 swift 做了一些优化,它对所有被观察对象只生成一个派生类,该派生类实现所有被观察对象的 setter 方法,这样就减少了派生类的数量,提供了效率。所有 NSKVONotifying_TestKVOKVC.People 这个派生类重写了 setAge,setName方法(留意:没重写其他set方法)。
接着来看最后两行输出,地址 0x00000001083a3c60 是 TestKVOKVC.People 类中的实现,而地址是 0x00000001089807fa 是派生类 NSKVONotifying_TestKVOKVC.People 类中的实现。那后面那个地址到底是什么呢?可以通过 lldb 的 info 命令 image lookup --address 0x00000001089807fa 查看该地址的信息:
(lldb) image lookup --address 0x00000001089807fa
Address: Foundation[0x00000000000637fa] (Foundation.__TEXT.__text + 401690)
Summary: Foundation`_NSSetObjectValueAndNotify
看起来它是 Foundation 框架提供的私有函数:_NSSetObjectValueAndNotify。更进一步,我们来看看 Foundation 到底提供了哪些用于 KVO 的辅助函数。打开 terminal,使用 nm -a 命令查看 Foundation 中的信息:
nm -a /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
其中查找到我们关注的函数:
00000000000c76bf t __NSSetBoolValueAndNotify
0000000000152ab2 t __NSSetBoolValueForKeyInIvar
00000000000c74c8 t __NSSetBoolValueForKeyWithMethod
00000000000997db t __NSSetCharValueAndNotify
0000000000064759 t __NSSetCharValueForKeyInIvar
00000000000646f1 t __NSSetCharValueForKeyWithMethod
000000000001bd73 t __NSSetCheckSize
00000000003f7a50 b __NSSetClass
00000000001019af t __NSSetDirectory2
00000000000ab4d3 t __NSSetDoubleValueAndNotify
0000000000152b5d t __NSSetDoubleValueForKeyInIvar
00000000000abf65 t __NSSetDoubleValueForKeyWithMethod
0000000000139763 T __NSSetExceptionRaiser
0000000000180650 t __NSSetFileModificationUNIXTime
00000000000c9cca t __NSSetFloatValueAndNotify
0000000000152bb6 t __NSSetFloatValueForKeyInIvar
0000000000152712 t __NSSetFloatValueForKeyWithMethod
00000000000c9ba9 t __NSSetIntValueAndNotify
0000000000152c0f t __NSSetIntValueForKeyInIvar
00000000000abefb t __NSSetIntValueForKeyWithMethod
00000000001817a7 T __NSSetLogCStringFunction
00000000000a5389 t __NSSetLongLongValueAndNotify
0000000000152d5f t __NSSetLongLongValueForKeyInIvar
00000000000a55e1 t __NSSetLongLongValueForKeyWithMethod
000000000015abd7 t __NSSetLongValueAndNotify
0000000000152cb7 t __NSSetLongValueForKeyInIvar
0000000000152779 t __NSSetLongValueForKeyWithMethod
000000000011651f T __NSSetMainBundle
00000000001531ad t __NSSetNilValueForKey
00000000000647b0 t __NSSetObjectSetIvarValueForKeyInIvar
0000000000096e38 t __NSSetObjectValueAndNotify
0000000000028b2d t __NSSetObjectValueForKeyInIvar
00000000000c0657 t __NSSetPointValueAndNotify
0000000000152e5f t __NSSetPointValueForKeyInIvar
00000000000c05f1 t __NSSetPointValueForKeyWithMethod
000000000015b067 t __NSSetRangeValueAndNotify
0000000000152ebc t __NSSetRangeValueForKeyInIvar
00000000001528b2 t __NSSetRangeValueForKeyWithMethod
0000000000099610 t __NSSetRectValueAndNotify
0000000000152f15 t __NSSetRectValueForKeyInIvar
000000000015291d t __NSSetRectValueForKeyWithMethod
000000000015ae1f t __NSSetShortValueAndNotify
0000000000152db3 t __NSSetShortValueForKeyInIvar
0000000000152849 t __NSSetShortValueForKeyWithMethod
00000000000af692 t __NSSetSizeValueAndNotify
0000000000152f86 t __NSSetSizeValueForKeyInIvar
00000000000af62d t __NSSetSizeValueForKeyWithMethod
000000000015aab3 t __NSSetUnsignedCharValueAndNotify
0000000000152b09 t __NSSetUnsignedCharValueForKeyInIvar
00000000001526a9 t __NSSetUnsignedCharValueForKeyWithMethod
00000000000e59a2 t __NSSetUnsignedIntValueAndNotify
0000000000152c63 t __NSSetUnsignedIntValueForKeyInIvar
0000000000103f5e t __NSSetUnsignedIntValueForKeyWithMethod
0000000000096fa8 t __NSSetUnsignedLongLongValueAndNotify
00000000000f5f93 t __NSSetUnsignedLongLongValueForKeyInIvar
00000000000c745d t __NSSetUnsignedLongLongValueForKeyWithMethod
000000000015acfa t __NSSetUnsignedLongValueAndNotify
0000000000152d0b t __NSSetUnsignedLongValueForKeyInIvar
00000000001527e1 t __NSSetUnsignedLongValueForKeyWithMethod
000000000015af43 t __NSSetUnsignedShortValueAndNotify
0000000000152e09 t __NSSetUnsignedShortValueForKeyInIvar
0000000000103ef5 t __NSSetUnsignedShortValueForKeyWithMethod
Foundation 提供了大部分基础数据类型的辅助函数,此外还包括一些常见的 Cocoa 结构体如 Point, Range, Rect, Size,这表明这些结构体也可以用于自动键值观察,但要注意除此之外的结构体就不能用于自动键值观察了。
// // People.swift // TestKVOKVC // // Created by yangjun zhu on 15/9/12. // Copyright © 2015年 Cactus. All rights reserved. // import Foundation class People: NSObject{ dynamic var name: String dynamic var age: Int dynamic var sex: Int var address: Address? init(name: String, age: Int, sex: Int, address: Address){ self.name = name self.age = age self.sex = sex self.address = address } }
// // PrincipleViewController.swift // TestKVOKVC // // Created by yangjun zhu on 15/9/12. // Copyright © 2015年 Cactus. All rights reserved. // import UIKit class PrincipleViewController: UIViewController { let people = People(name: "Owen", age: 1, sex: 1, address: Address()) let namePeople = People(name: "Owen", age: 1, sex: 1, address: Address()) let nameAgePeople = People(name: "Owen", age: 1, sex: 1, address: Address()) deinit{ self.namePeople .removeObserver(self, forKeyPath: "name") self.nameAgePeople .removeObserver(self, forKeyPath: "name") self.nameAgePeople .removeObserver(self, forKeyPath: "age") } private var myContext = 0 override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. self.namePeople.addObserver( self, forKeyPath: "name", options: NSKeyValueObservingOptions([.New, .Old]), context: &myContext) self.nameAgePeople.addObserver( self, forKeyPath: "name", options: NSKeyValueObservingOptions([.New, .Old]), context: &myContext) self.nameAgePeople.addObserver( self, forKeyPath: "age", options: NSKeyValueObservingOptions([.New, .Old]), context: &myContext) self.printDescription("people", obj: people) self.printDescription("namePeople",obj: namePeople) self.printDescription("nameAgePeople",obj: nameAgePeople) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } private func classMethodNames(c: AnyObject) -> [String] { var arr = [String]() var methodCount: CUnsignedInt = 0; let methodList = class_copyMethodList(object_getClass(c), &methodCount); for i in 0...methodCount { arr.append( NSStringFromSelector(method_getName(methodList[Int(i)]))) } free(methodList); return arr; } private func printDescription(objectName: String, obj: AnyObject) { print("-----------------start------------") print("对象变量名字:",objectName) print("对象:",obj) print("类:",NSStringFromClass(obj.classForCoder)) print("元类:",NSStringFromClass(object_getClass(obj))) print("实现的方法:",self.classMethodNames(obj).joinWithSeparator(", ")) print("-----------------end------------") } /* func observeValueForKeyPath(keyPath: String?, object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { if let change = change where context == &myContext{ print(keyPath, "改变了") print(keyPath, "new:" , change[NSKeyValueChangeNewKey]) print(keyPath, "old:" , change[NSKeyValueChangeOldKey]) return; } super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context) } */ }
输出:
-----------------start------------
对象变量名字: people
对象: <TestKVOKVC.People: 0x7fa449c14a60>
类: TestKVOKVC.People
元类: TestKVOKVC.People
实现的方法: setAge:, setSex:, age, sex, initWithName:age:sex:address:, name, address, .cxx_destruct, init, setName:, setAddress:,
-----------------end------------
-----------------start------------
对象变量名字: namePeople
对象: <TestKVOKVC.People: 0x7fa449c61e20>
类: TestKVOKVC.People
元类: NSKVONotifying_TestKVOKVC.People
实现的方法: setAge:, setName:, class, dealloc, _isKVOA,
-----------------end------------
-----------------start------------
对象变量名字: nameAgePeople
对象: <TestKVOKVC.People: 0x7fa449cbe990>
类: TestKVOKVC.People
元类: NSKVONotifying_TestKVOKVC.People
实现的方法: setAge:, setName:, class, dealloc, _isKVOA,
-----------------end------------
0x00000001083a3c60
0x00000001089807fa
0x00000001083a3c60
0x00000001089807fa
可以看到输出类名始终为:TestKVOKVC.People,这是因为新诞生的派生类重写了 -class 方法声称它就是起初的基类,只有使用 runtime 函数 object_getClass 才能一睹芳容:NSKVONotifying_TestKVOKVC.People。注意看:name,age 两个被观察对象真正的类型都是 NSKVONotifying_TestKVOKVC.People,而且该类实现了:setAge:, setName:, class, dealloc, _isKVOA 这些方法。其中 setAge:, setName:重写实现通知机制, class声明原来的类 , dealloc释放资源,私有方法 _isKVOA 是用来标示该类是一个 KVO 机制声称的类。在这里 swift 做了一些优化,它对所有被观察对象只生成一个派生类,该派生类实现所有被观察对象的 setter 方法,这样就减少了派生类的数量,提供了效率。所有 NSKVONotifying_TestKVOKVC.People 这个派生类重写了 setAge,setName方法(留意:没重写其他set方法)。
接着来看最后两行输出,地址 0x00000001083a3c60 是 TestKVOKVC.People 类中的实现,而地址是 0x00000001089807fa 是派生类 NSKVONotifying_TestKVOKVC.People 类中的实现。那后面那个地址到底是什么呢?可以通过 lldb 的 info 命令 image lookup --address 0x00000001089807fa 查看该地址的信息:
(lldb) image lookup --address 0x00000001089807fa
Address: Foundation[0x00000000000637fa] (Foundation.__TEXT.__text + 401690)
Summary: Foundation`_NSSetObjectValueAndNotify
看起来它是 Foundation 框架提供的私有函数:_NSSetObjectValueAndNotify。更进一步,我们来看看 Foundation 到底提供了哪些用于 KVO 的辅助函数。打开 terminal,使用 nm -a 命令查看 Foundation 中的信息:
nm -a /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
其中查找到我们关注的函数:
00000000000c76bf t __NSSetBoolValueAndNotify
0000000000152ab2 t __NSSetBoolValueForKeyInIvar
00000000000c74c8 t __NSSetBoolValueForKeyWithMethod
00000000000997db t __NSSetCharValueAndNotify
0000000000064759 t __NSSetCharValueForKeyInIvar
00000000000646f1 t __NSSetCharValueForKeyWithMethod
000000000001bd73 t __NSSetCheckSize
00000000003f7a50 b __NSSetClass
00000000001019af t __NSSetDirectory2
00000000000ab4d3 t __NSSetDoubleValueAndNotify
0000000000152b5d t __NSSetDoubleValueForKeyInIvar
00000000000abf65 t __NSSetDoubleValueForKeyWithMethod
0000000000139763 T __NSSetExceptionRaiser
0000000000180650 t __NSSetFileModificationUNIXTime
00000000000c9cca t __NSSetFloatValueAndNotify
0000000000152bb6 t __NSSetFloatValueForKeyInIvar
0000000000152712 t __NSSetFloatValueForKeyWithMethod
00000000000c9ba9 t __NSSetIntValueAndNotify
0000000000152c0f t __NSSetIntValueForKeyInIvar
00000000000abefb t __NSSetIntValueForKeyWithMethod
00000000001817a7 T __NSSetLogCStringFunction
00000000000a5389 t __NSSetLongLongValueAndNotify
0000000000152d5f t __NSSetLongLongValueForKeyInIvar
00000000000a55e1 t __NSSetLongLongValueForKeyWithMethod
000000000015abd7 t __NSSetLongValueAndNotify
0000000000152cb7 t __NSSetLongValueForKeyInIvar
0000000000152779 t __NSSetLongValueForKeyWithMethod
000000000011651f T __NSSetMainBundle
00000000001531ad t __NSSetNilValueForKey
00000000000647b0 t __NSSetObjectSetIvarValueForKeyInIvar
0000000000096e38 t __NSSetObjectValueAndNotify
0000000000028b2d t __NSSetObjectValueForKeyInIvar
00000000000c0657 t __NSSetPointValueAndNotify
0000000000152e5f t __NSSetPointValueForKeyInIvar
00000000000c05f1 t __NSSetPointValueForKeyWithMethod
000000000015b067 t __NSSetRangeValueAndNotify
0000000000152ebc t __NSSetRangeValueForKeyInIvar
00000000001528b2 t __NSSetRangeValueForKeyWithMethod
0000000000099610 t __NSSetRectValueAndNotify
0000000000152f15 t __NSSetRectValueForKeyInIvar
000000000015291d t __NSSetRectValueForKeyWithMethod
000000000015ae1f t __NSSetShortValueAndNotify
0000000000152db3 t __NSSetShortValueForKeyInIvar
0000000000152849 t __NSSetShortValueForKeyWithMethod
00000000000af692 t __NSSetSizeValueAndNotify
0000000000152f86 t __NSSetSizeValueForKeyInIvar
00000000000af62d t __NSSetSizeValueForKeyWithMethod
000000000015aab3 t __NSSetUnsignedCharValueAndNotify
0000000000152b09 t __NSSetUnsignedCharValueForKeyInIvar
00000000001526a9 t __NSSetUnsignedCharValueForKeyWithMethod
00000000000e59a2 t __NSSetUnsignedIntValueAndNotify
0000000000152c63 t __NSSetUnsignedIntValueForKeyInIvar
0000000000103f5e t __NSSetUnsignedIntValueForKeyWithMethod
0000000000096fa8 t __NSSetUnsignedLongLongValueAndNotify
00000000000f5f93 t __NSSetUnsignedLongLongValueForKeyInIvar
00000000000c745d t __NSSetUnsignedLongLongValueForKeyWithMethod
000000000015acfa t __NSSetUnsignedLongValueAndNotify
0000000000152d0b t __NSSetUnsignedLongValueForKeyInIvar
00000000001527e1 t __NSSetUnsignedLongValueForKeyWithMethod
000000000015af43 t __NSSetUnsignedShortValueAndNotify
0000000000152e09 t __NSSetUnsignedShortValueForKeyInIvar
0000000000103ef5 t __NSSetUnsignedShortValueForKeyWithMethod
Foundation 提供了大部分基础数据类型的辅助函数,此外还包括一些常见的 Cocoa 结构体如 Point, Range, Rect, Size,这表明这些结构体也可以用于自动键值观察,但要注意除此之外的结构体就不能用于自动键值观察了。
待续...........
demo:https://github.com/easyui/TestKVO
参考:
http://blog.csdn.net/wzzvictory/article/details/9674431?utm_source=tuicool
http://blog.csdn.net/kesalin/article/details/8194240
http://www.cnblogs.com/dark-angel/archive/2011/05/05/2037734.html
http://objccn.io/issue-7-3/#key-value-validation
http://www.cnblogs.com/496668219long/p/4470923.html
http://www.jianshu.com/p/e036e53d240e
http://blog.sina.com.cn/s/blog_8a38e5240100u2yw.html
http://www.androiddev.net/kvo/
http://nshipster.com/key-value-observing/
http://tech.glowing.com/cn/implement-kvo/
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVOImplementation.html
相关推荐
以下是Objective-C 2.0的一些核心知识点: 1. **消息传递**:Objective-C中的对象通过消息传递进行通信。当你调用一个方法时,实际上是向对象发送一个消息。例如,`[object method]`表示向`object`发送`method`消息...
本知识点主要探讨如何基于AFNetworking实现队列下载,即多个任务按照一定的顺序或者并发执行,以提高用户体验并有效地管理网络资源。 一、AFNetworking简介 AFNetworking是由Mattt Thompson和Mike Taylor创建的一个...
以下是对备忘单中涵盖的一些关键知识点的详细说明: 1. **类别(Category)**: 类别允许我们在不继承的情况下扩展已有的类。它可以在不修改原有类源代码的情况下添加方法,常用于为Foundation框架中的类添加便捷...
1、文件内容:qt5-qtmultimedia-5.9.7-1.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/qt5-qtmultimedia-5.9.7-1.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、安装指导:私信博主,全程指导安装
资源说明: 1:csdn平台资源详情页的文档预览若发现'异常',属平台多文档切片混合解析和叠加展示风格,请放心使用。 2:32页图文详解文档(从零开始项目全套环境工具安装搭建调试运行部署,保姆级图文详解),旨在为更多的人甚至零基础的人也能运行、使用和学习。 3:配套毕业论文,万字长文,word文档,支持二次编辑。 4:范例参考答辩ppt,pptx格式,支持二次编辑。 5:工具环境、ppt参考模板、相关电子教程、视频教学资源分享。 6:资源项目源码均已通过严格测试验证,保证能够正常运行,本项目仅用作交流学习参考,请切勿用于商业用途。 7:项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通。 内容概要: 本系统基于B/S网络结构,在IDEA中开发。服务端用Java并借ssm框架(Spring+SpringMVC+MyBatis)搭建后台。用MySQL存储数据,可靠性强。 能学到什么: 使用ssm搭建后台。学习使用jsp、html构建交互界面、前后端数据交互、MySQL管理数据、从零开始环境搭建、调试、运行、打包、部署流程。
资源说明: 1:csdn平台资源详情页的文档预览若发现'异常',属平台多文档切片混合解析和叠加展示风格,请放心使用。 2:32页图文详解文档(从零开始项目全套环境工具安装搭建调试运行部署,保姆级图文详解),旨在为更多的人甚至零基础的人也能运行、使用和学习。 3:范例参考毕业论文,万字长文,word文档,支持二次编辑。 4:范例参考答辩ppt,pptx格式,支持二次编辑。 5:工具环境、ppt参考模板、相关电子教程、视频教学资源分享。 6:资源项目源码均已通过严格测试验证,保证能够正常运行,本项目仅用作交流学习参考,请切勿用于商业用途。 7:项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通。 内容概要: 本系统基于B/S网络结构,在IDEA中开发。服务端用Java并借ssm框架(Spring+SpringMVC+MyBatis)搭建后台。用MySQL存储数据,可靠性强。 能学到什么: 使用ssm搭建后台。VUE框架构建前端交互界面、前后端数据交互、MySQL管理数据、从零开始环境搭建、调试、运行、打包、部署流程。
Self-supervised Equivariant Attention Mechanismfor Weakly Supervised Semantic Segmentation,含有完整的代码和论文
本资源包含数据集有猫的三种声音-高音声、哈气声和喵呜声。 通过python、pytorch环境运行。 环境的安装可参考: https://blog.csdn.net/no_work/article/details/145416261 代码整体是非常简便的,总共三个py部分和一个数据集在data文件夹下。 运行python 01数据集文本生成制作.py 会在logs文件夹下生成2个txt文本,分别存放了wav音频的路径和对应的标签。 运行python 02train.py就会训练这个txt文本里面的数据,并将训练的模型与验证集里面的数据进行验证。 最后模型也是保存在logs文件夹下。 最后运行python 03pyqt.py即可加载训练好的模型,对输入的音频进行识别。
资源说明: 1:csdn平台资源详情页的文档预览若发现'异常',属平台多文档切片混合解析和叠加展示风格,请放心使用。 2:32页图文详解文档(从零开始项目全套环境工具安装搭建调试运行部署,保姆级图文详解),旨在为更多的人甚至零基础的人也能运行、使用和学习。 3:配套毕业论文,万字长文,word文档,支持二次编辑。 4:范例参考答辩ppt,pptx格式,支持二次编辑。 5:工具环境、ppt参考模板、相关电子教程、视频教学资源分享。 6:资源项目源码均已通过严格测试验证,保证能够正常运行,本项目仅用作交流学习参考,请切勿用于商业用途。 7:项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通。 内容概要: 本系统基于B/S网络结构,在IDEA中开发。服务端用Java并借ssm框架(Spring+SpringMVC+MyBatis)搭建后台。用MySQL存储数据,可靠性强。 能学到什么: 使用ssm搭建后台。学习使用jsp、html构建交互界面、前后端数据交互、MySQL管理数据、从零开始环境搭建、调试、运行、打包、部署流程。
资源说明: 1:csdn平台资源详情页的文档预览若发现'异常',属平台多文档切片混合解析和叠加展示风格,请放心使用。 2:32页图文详解文档(从零开始项目全套环境工具安装搭建调试运行部署,保姆级图文详解),旨在为更多的人甚至零基础的人也能运行、使用和学习。 3:配套毕业论文,万字长文,word文档,支持二次编辑。 4:范例参考答辩ppt,pptx格式,支持二次编辑。 5:工具环境、ppt参考模板、相关电子教程、视频教学资源分享。 6:资源项目源码均已通过严格测试验证,保证能够正常运行,本项目仅用作交流学习参考,请切勿用于商业用途。 7:项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通。 内容概要: 本系统基于B/S网络结构,在IDEA中开发。服务端用Java并借ssm框架(Spring+SpringMVC+MyBatis)搭建后台。用MySQL存储数据,可靠性强。 能学到什么: 使用ssm搭建后台。学习使用jsp、html构建交互界面、前后端数据交互、MySQL管理数据、从零开始环境搭建、调试、运行、打包、部署流程。
Global Context Networks,含有完整的代码和论文
1、文件内容:rhn-setup-gnome-2.0.2-24.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/rhn-setup-gnome-2.0.2-24.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、安装指导:私信博主,全程指导安装
基于FAST与MATLAB Simulink联合仿真的风机变桨控制研究:独立与统一变桨在非线性风力发电机中的对比与应用分析,风机变桨控制基于FAST与MATLAB SIMULINK联合仿真模型非线性风力发电机的 PID独立变桨和统一变桨控制下仿真模型,对于5WM非线性风机风机进行控制 链接simulink的scope出转速对比,桨距角对比,叶片挥舞力矩,轮毂处偏航力矩,俯仰力矩等载荷数据对比图,在trubsim生成的3D湍流风环境下模拟 统一变桨反馈信号是转速,独立变桨反馈是叶根载荷 包含openfast与matlab simulink联合仿真的建模 NREL免费提供的5MW风机参数建模 可以提供参考文献 ,FAST模型; MATLAB SIMULINK联合仿真; 风机变桨控制; 非线性风力发电机; PID独立变桨控制; 统一变桨控制; 5WM风机; 仿真模型; 桨距角对比; 转速对比; 3D湍流风环境模拟; OpenFAST与MATLAB联合仿真建模; NREL 5MW风机参数建模。,基于OpenFAST与MATLAB/Simulink联合仿真模型的5MW风机变桨控制研究
资源说明: 1:csdn平台资源详情页的文档预览若发现'异常',属平台多文档切片混合解析和叠加展示风格,请放心使用。 2:32页图文详解文档(从零开始项目全套环境工具安装搭建调试运行部署,保姆级图文详解),旨在为更多的人甚至零基础的人也能运行、使用和学习。 3:配套毕业论文,万字长文,word文档,支持二次编辑。 4:配套答辩ppt,pptx格式,支持二次编辑。 5:工具环境、ppt参考模板、相关电子教程、视频教学资源分享。 6:资源项目源码均已通过严格测试验证,保证能够正常运行,本项目仅用作交流学习参考,请切勿用于商业用途。 7:项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通。 内容概要: 本系统基于B/S网络结构,在IDEA中开发。服务端用Java并借ssm框架(Spring+SpringMVC+MyBatis)搭建后台。用MySQL存储数据,可靠性强。 能学到什么: 使用ssm搭建后台。VUE框架构建前端交互界面、前后端数据交互、MySQL管理数据、从零开始环境搭建、调试、运行、打包、部署流程。
1、文件内容:qt5-qtimageformats-doc-5.9.7-2.el7_9.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/qt5-qtimageformats-doc-5.9.7-2.el7_9.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、安装指导:私信博主,全程指导安装
基于Matlab Simulink的有源电力滤波器(APF)模型治理不控整流与三相不平衡电能质量问题仿真演示,有源电力滤波器(APF)模型 Matlab simulink 质量过硬 可用于治理不控整流和不平衡负载带来的电能质量问题:仿真总时长0.3s,0.1s时接入APF, 0.1-0.2s治理不控整流带来的谐波电流,0.2-0.3治理三相不平衡带来的不平衡电流。 ,核心关键词:有源电力滤波器(APF)模型; Matlab simulink; 质量过硬; 治理电能质量问题; 仿真; 不控整流; 不平衡负载; 谐波电流; 三相不平衡电流。,有源电力滤波器模型仿真:治理不控整流与三相不平衡的电能质量优化
1、文件内容:qt5-qtserialport-doc-5.9.7-1.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/qt5-qtserialport-doc-5.9.7-1.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、安装指导:私信博主,全程指导安装
资源说明: 1:csdn平台资源详情页的文档预览若发现'异常',属平台多文档切片混合解析和叠加展示风格,请放心使用。 2:32页图文详解文档(从零开始项目全套环境工具安装搭建调试运行部署,保姆级图文详解),旨在为更多的人甚至零基础的人也能运行、使用和学习。 3:配套毕业论文,万字长文,word文档,支持二次编辑。 4:配套答辩ppt,pptx格式,支持二次编辑。 5:工具环境、ppt参考模板、相关电子教程、视频教学资源分享。 6:资源项目源码均已通过严格测试验证,保证能够正常运行,本项目仅用作交流学习参考,请切勿用于商业用途。 7:项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通。 内容概要: 本系统基于B/S网络结构,在IDEA中开发。服务端用Java并借ssm框架(Spring+SpringMVC+MyBatis)搭建后台。用MySQL存储数据,可靠性强。 能学到什么: 使用ssm搭建后台。学习使用jsp、html构建交互界面、前后端数据交互、MySQL管理数据、从零开始环境搭建、调试、运行、打包、部署流程。
通过 MATLAB 读取 N10 激光雷达 的数据,并进行 实时 3D 点云可视化。数据通过 串口 传输,并经过解析后转换为 三维坐标点,最终使用 pcplayer 进行动态渲染。
基于雨流计数法的源荷储双层协同优化配置:储能系统寿命评估与充放电策略研究,基于雨流计数法的源-荷-储双层协同优化配置 关键词:双层规划 雨流计算法 储能优化配置 参考文档:《储能系统容量优化配置及全寿命周期经济性评估方法研究》第三章 仿真平台:MATLAB CPLEX 主要内容:代码主要做的是一个源荷储优化配置的问题,采用双层优化,外层优化目标的求解依赖于内层优化的储能系统充放电曲线,基于储能系统充放电曲线,采用雨流计数法电池健康状态数学模型,对决策变量储能功率和容量的储能系统寿命年限进行评估;内层储能系统充放电曲线的优化受外层储能功率和容量决策变量的影响,不同的功率和容量下,储能装置的优化充放电功率曲线存在差异。 代码非常精品,注释保姆级,靠谱值得信赖。 ,双层规划;雨流计数法;储能优化配置;充放电曲线;电池健康状态。,基于雨流计数法的双层协同储能优化配置研究