使用Realm和Swift编写一个ToDo应用 作者:HOSSAM GHAREEB,时间:2015/11/28翻译:BigNerdCoding, 如有错误欢迎指出。原文链接 在去年智能手机的大更新之后,很多工具也同时被开发出来了。这些工具让我们开发者发布一个高性能、高质量的应用的变的更加简单了。在应用商店获得高排名以及不再很容易。而且让应用更容易拓展也是很困难的一件事。当你的应用成功的拥有百万级别的用户的时候,你需要注意应用中的所有事情以及所有操作。因此,现在每个开发者都需要面临的一个问题就是处理数据库。而这又是一件让人感到非常头疼的事情,大多数的开发者会在SQLite和Core Data中挑选一个。曾经我是Core Data的拥趸,因为它在处理数据以及持久化数据方面功能非常强大。但是后来我发现使用Core Data会浪费很多时间。现在我会使用Realm,该框架能够很好的替换SQLite和Core Data。 Realm是什么 Realm是一个跨平台的手机端数据库支持iOS(Swift和Object双语言版本)、安卓。相比于SQLite和Core Data更好也更快。除此之外,它的使用也很方便之需要几行代码就可以搞定。Realm是一个开源产品你可以免费试用。Realm之所以会出现是因为在过去的十年中移动数据库没有任何可喜的更新。过去在处理移动数据库的时候,你几乎只能选择SQLite或者在其基础上进行封装的Core Data。因为Realm并不是一个ORM(对象关系映射)且有自己的持久化引擎使得Realm容易使用并且拥有很好的性能和速度。 为什么选择Realm Realm快的难以置信并且易用,你能看见任何你需要的东西,并且只需要几行代码就可以完成数据库的读写操作。这里我会列出所有在移动端使用Realm的好处和理由: 安装简单:在后面你会发现安装Realm比你想象的还要简单,之需要在Cocoapods中添加简单的命令就能使用了。 速度:Realm远快过于SQLite和Core Data,官方提供的比较证据 跨平台:Realm的数据库文件是跨平台的,它可以在iOS和Android中进行分享。无论你是使用Java、Object-C、还是Swift,你都可以使用高级的模型。 可拓展性:当你的手机应用拥有大量的用户以及数据记录的时候可拓展就是很重要的一个特征。拓展性问题从一开始设计和选择工具的时候就需要进行认真的考虑。Realm在能够高效处理大数据量的同时依然拥有着非常好的拓展性。在应用中引入该框架会让程序的速度得到提升。 良好的文档支持:Realm团队提供了可读性强、组织良好的的丰富文档给大家。如果你依旧有问题解决不了的话,可以在 Twitter、Github、Stackoverflow上去向它们寻求帮助和解答。 可靠:Realm依旧被大量的创业团队和公司的移动应用使用像:Pinterest、Dubsmash、Hipmunk。 免费:如此强大,而且还是完全免费的。 开始干活 让我们Realm使用教程,并用它创建一个Swift语言版本的iPhone简单Todo应用。用户在该应用中可以添加多个任务链表,每个链表里面又会有多个任务。每个任务都有一个标题、备注、到期时间,一个图像附件以及一个标记是否完成的标记量。在开始编写工程之前我们首先需要配置Xcode并安装Realm工作所需的一个工具。 需要的条件 下列条件必须满足: iOS 8 or later、OS X 10.9 or later。 Xcode 6.3 or later。 Realm的有两个Swift版本,一个是2.0版本另一个是1.2版本。我们在教程中使用的是2.0版本。你也可以选择使用1.2版本的,但是该版本在未来不会被维护和支持,因此最安全的办法就是使用2.0版本。 配置Xcode并安装工具 再开始配置Xcode之前请确保你已经安装了CocoaPods,我们需要使用它在Xcode工程中安装Realm。如果你对CocoaPods不熟悉的话,你可以去官网操作安装教程。 现在,我们创建一个"Single View Application"模版的工程,并将工程命名为“RealmTasks”或者你喜欢的名称。请确保使用的是Swift语言。接下来我们在终端中切换到当前工程的目录并按照下面步骤初始化工程的CocoaPods。 pod init 使用编辑器生成的文件podfile,并在文件中添加如下内容: 接下来运行命令"pod install"去下载安装Realm到你的工程里面。当安装完成后,你会发现文件夹下面又一个新的Xcode workspace被创建了。打开RealmTasks.xcworkspace文件,你会看见如下界面: 现在Realm已经能够使用了,但是我们还是安装一些工具类帮助我们更加容易的使用Realm。 安装Realm插件 Realm团队为Xcode提供了很好的插件,该插件能够创建Realm模型。我们使用Alcatraz来安装这个插件。该工具可以很好的帮助你自动安装那些开源的插件,模版、颜色主题。对于那些不知道Alcatrza的开发者来说,这可以节省很多的时间和精力。直接使用下面的命令安装Alcatrza: curl -fsSL https://raw.githubusercontent.com/supermarin/Alcatraz/deploy/Scripts/install.sh | sh 接下来在Xcode中选择Window菜单栏下面的Package Manager,如下图: 在弹出的窗口中选择你需要安装的类型,并在搜索框中输入对应的插件、模版或者主题。我们选择Plugins,输入"Realm",在出现的结果里面选择"RealmPlugin"并安装。如下图: 此处可能在Xcode7.1以上版本会出现一些问题,解决方法 Realm Browser 最后一个工具是Realm Browser。该浏览器可以帮助你查看或者编辑你的.realm数据库文件。这些数据文件在你的应用中被创建出来,并且包含了里面的实体、属性、以及数据表中的纪录。这些文件如之前所说的一样可以在像iOS、Android这样不同的平台之间分享。你可以在iTunes store下载到最新版本的工具。打开该应用选择Tools -> Genetate demo database,应用会为你新建一个测试数据库文件你可以在浏览器中看到所有的纪录。如下图: 正如上图显示的,类RealmTestClass1有1000条纪录以及不同类型的参数(列)。我们会在下面接受它支持的类型。 现在一切准备工作都已经完成了。开始编码吧。 数据库Model类 游戏开始了!首先我们需要新建一个模型类。可以通过创建一个继承与Object的Swift类。考虑到Object是所有Realm model类的基类,你可以拓展任何拓展自Obeject的Realm model类。当你创建自己的类的时候,理所当然你需要定义属性。Realm支持下面各种类型的属性: Int, Int8, Int16, Int32, and Int64 Boolean Float String NSDate NSData Class extends Object => Used for One-to-one relations List => Used for one-to-many relations List在Realm类中表示对象实例的集合,就像上面演示数据库截图表示的那样。截图中的最后一列就是一个存在于另一张表中纪录指针的数组。在使用Realm模型类的时候,你可以像对待其他Swift类一样对待它。例如,你可以在类里面添加函数方法,协议。 Talk is cheap,show me the code ? 我们使用刚才安装的Realm插件创建一个Realm类。在Xcode中新建文件,在左侧选择Realm。如图: 选择Swift语言,类名为Task。如下图: 现在为该类添加属性。 属性 我们需要在Task类中添加属性,每一个Task都会有名称、创建日期、备注、是否完成。添加完成之后代码如下: class Task: Object { dynamic var name = "" dynamic var createdAt = NSDate() dynamic var notes = "" dynamic var isCompleted = false // Specify properties to ignore (Realm won't persist these) // override static func ignoredProperties() -> [String] { // return [] // } } 你可以发现添加的所有属性都被声明为dynamic var,之所以这样是为了让这些属性能够被底层数据库数据访问到。 接下来,我们定义一个TaskList类,该类存储多个任务: class TaskList: Object { dynamic var name = "" dynamic var createdAt = NSDate() let tasks = List() // Specify properties to ignore (Realm won't persist these) // override static func ignoredProperties() -> [String] { // return [] // } } TaskList类有名称、创建时间、任务链表。下面是一些说明补充: List对应一个任务列表有多个任务这种一对多的关系。 List于数组的类似,用户可以通过下标索引来访问链表中的数据。注意:链表中的数据必须是用一个类型。 List是一个泛型数据类型,之所以不在该泛型属性前面添加dynamic声明是因为泛型属性无法通过Objective-C的运行时表示。 Realm中关系的建立就像你前面看到的一对多的实现一样简单直接。一个简单的一对一的例子如下: class Person: Object{ dynamic var name = "" } class Car: Object{ dynamic var owner:Person? } 上面的示例代码很好的表现了一对一的关系:每个人都有一个对应的车主。 到目前为止,我们已经建好了基础的model类。接下来我们继续创建Todo应用的教程。首先,下载代码在Xcode7或者更高的版本中运行,你会看见下面截图一样的界面: 在这个工程中,我添加了两个视图控制器:TasksViewController和TaskListViewController。前面一个视图控制器是用来展示一个任务的细节,第二个视图控制器是用来显示所有的任务。在列表视图中你点击+按键添加一个任务列表。选择一个视图列表会跳转到另一个视图中添加多个任务。 带着演示应用的基本概念,现在让我们看看如何添加一个任务链表到Realm数据库中。为了实现这个功能,我们需要解决下面两件事: 创建一个新的TaskList model对象并将其保存到Realm. 使用查询语句从数据库中读出数据并更新界面UI。 为了将对象保存到Realm,你所需要做的就是实例化Obeject子类的model对象并将其写入到数据库。下面就是代码示例: let taskListA = TaskList() taskListA.name = "Wishlist" let wish1 = Task() wish1.name = "iPhone6s" wish1.notes = "64 GB, Gold" let wish2 = Task(value: ["name": "Game Console", "notes": "Playstation 4, 1 TB"]) let wish3 = Task(value: ["Car", NSDate(), "Auto R8", false]) taskListA.tasks.appendContentsOf([wish1, wish2, wish3]) 我们创建了一个任务链表,并使用初始化方法进行了实例化设置了部分属性。然后我们创建了三个task类型的对象(wish1, wish2 and wish3)。在这里我使用了三种方法来创建Realm对象: 使用Realm类的实例化方法创建wish1并设置属性 通过传递键值类型的字典类型的属性来创建wish2。 通过传递一个数组来创建wish3。数组中的值与类中声明的属性顺序一样。 嵌套对象 Realm中另一个创建对象的方法就是嵌套对象。该方法在对象关系是一对一或者一对多的时候可以使用(意味着你有一个Object类型的属性或者一个List类型的属性)。如果你使用了上面的方法2或者方法3的话,你可以使用一个表示属性的数组或者字典来取代该方法,代码如下: let tasklistB = TaskList(value: ["MoviesList",NSDate(), [["The Martian", NSDate(), "", false], ["The Maze Runner", NSDate(), "", true]]]) 在上面的代码中,我们新建了一个电影链表,设置了名称、时间、任务数组。每一个任务又是通过属性数组创建的。例如[“The Maze Runner”, NSDate(), “”, true]就表示名称、时间、备注、是否已经完成了。 持久化Realm中的对象 现在你知道了如何创建并使用Realm对象。但是为了在应用重新启动的时候依旧能够使用这些对象,你需要通过Realm数据库的写事务来进行对象持久化。一旦对象数据被持久化了并存在于Realm数据库中,你就可以在任何线程中访问这些对象。为了执行这个写事务,你需要一个Realm对象。一个Realm的实例就代表一个Realm数据库。你可以如下创建该实例: let uiRealm = try! Realm() 我们将该实例定义在AppDelegate.swift文件的上面这样就可以在所有的文件中使用了。后面你可以如下简单的调用写方法: uiRealm.write { () -> Void in uiRealm.add([taskListA, taskListB]) } 首先uiRealm对象在AppDelegate类中创建好了并且能够在整个应用中使用。每一个线程里面Realm对象只能创建一次,因为Realm对象不是线程安全的并且不能在不同的线程中共享。如果你想在别的线程里面执行写事务,你需要创建一个新的Realm对象。这里创建的uiRealm对象就是在UI线程中使用的。 现在我们回到app中,当用户点击创建按键的时候我们需要保存一个task lists。在TasksViewController文件的displayAlterToAddTask方法中,我们如下创建对象: let createAction = UIAlertAction(title: doneTitle, style: UIAlertActionStyle.Default) { (action) -> Void in let taskName = alertController.textFields?.first?.text if updatedTask != nil{ // update mode uiRealm.write({ () -> Void in updatedTask.name = taskName! self.readTasksAndUpateUI() }) } else{ let newTask = Task() newTask.name = taskName! uiRealm.write({ () -> Void in self.selectedList.tasks.append(newTask) self.readTasksAndUpateUI() }) } } 在上面的代码中,我们从text field中获取名称,然后调用Realm的写方法保存该任务链表。 请注意:当有多个线程同时执行写操作的事务时,它们都会阻塞对方的线程并且也会阻塞自己所在的线程。所以你应该在一个单独的线程操作里面执行写事务而不是在UI线程里面。另一件事时:读操作不会阻塞写事务的操作。这在用户浏览应用并伴随很多读操作的同时进行后台数据写事务时很有帮助的。 检索对象 你已经知道在Realm中进行数据写操作了,但是如果你不知道如何检索处这些数据那么写操作也就没有意义了!其实Realm中查询很简单直接。你传递一些自定义的查询条件,然后执行查询,筛选出来的结果就会展示在你的面前。你可以将查询得到的结果看成时Swift中的数组,因为它们有着相似的接口。 当你实例化一个结果对象之后,很容易就能获取磁盘中的数据。事务中对数据的任何修改都会直接影响磁盘中的数据。在Realm中你可以通过调用以类名作为参数的方法得到结果。下面我们看看如何读出TaskLists并更新UI: 我们已经在TasksListsViewController定义了属性: var lists : Results! readTasksAndUpdateUI方法的实现: func readTasksAndUpdateUI(){ lists = uiRealm.objects(TaskList) self.taskListsTableView.setEditing(false, animated: true) self.taskListsTableView.reloadData() } 在tableView(_:cellForRowAtIndexPath:_) 方法里面,我们显示任务链表名以及任务数: func tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{ let cell = tableView.dequeueReusableCellWithIdentifier("listCell") let list = lists[indexPath.row] cell?.textLabel?.text = list.name cell?.detailTextLabel?.text = "\(list.tasks.count) Tasks" return cell! } 是不是很简单?最后我们需要在viewWillAppear中调用readTasksAndUpdateUI函数,确保每次视图出现的时候都是最新的。 override func viewWillAppear(animated: Bool) { readTasksAndUpdateUI() } 以上就是使用Realm进行读写task lists的内容了。下面,我们需要知道Realm中如何进行删除和更新操作。在开始之前,我们先来看看工程中lists的编辑、删除操作的代码。 首先在TaskListsViewController中有一个isEditingMode的布尔变量,用于编辑和正常模式的切换。 var isEditingMode = false 当点击编辑按键的时候,didClickOnEditButton方法将被调用: @IBAction func didClickOnEditButton(sender: UIBarButtonItem) { isEditingMode = !isEditingMode self.taskListsTableView.setEditing(isEditingMode, animated: true) } 该动作使用table view中的setEditing方法来设置是否处于编辑模式。在table view中编辑模式下的默认方法就是删除改单元,但是在iOS8.0的UITableViewDelegate中引入了一个editActionsForRowAtIndexPath方法,该方法用于当用户滑动单元格的时候定制自己的方法。 我们添加删除、编辑两个方法,实现如下: func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? { let deleteAction = UITableViewRowAction(style: UITableViewRowActionStyle.Destructive, title: "Delete") { (deleteAction, indexPath) -> Void in //Deletion will go here let listToBeDeleted = self.lists[indexPath.row] uiRealm.write({ () -> Void in uiRealm.delete(listToBeDeleted) self.readTasksAndUpdateUI() }) } let editAction = UITableViewRowAction(style: UITableViewRowActionStyle.Normal, title: "Edit") { (editAction, indexPath) -> Void in // Editing will go here let listToBeUpdated = self.lists[indexPath.row] self.displayAlertToAddTaskList(listToBeUpdated) } return [deleteAction, editAction] } 我们通过带有style、title、handler的UITableViewRowAction添加了两个action。现在当你向左滑动或者点击编辑的时候界面会是下面这样: 上面是关于UI如何响应删除和更新动作的。 删除对象 为了删除Ralm数据库中的对象或者数据,你可以通过传递需要的对象给delete方法。当然,改操作应该在一个写事务内部。下面的代码就是删除操作的代码实现: let listToBeDeleted = self.lists[indexPath.row] uiRealm.write({ () -> Void in uiRealm.delete(listToBeDeleted) self.readTasksAndUpdateUI() }) 当删除对象后调用readTasksAndUpdateUI方法来更新界面。 出了上面的删除一个对象,还可以调用Realm中的deleteAll方法来删除数据库中索引类和数据。该方法在当前用户退出应用而你需要清除数据库中的所有持久化数据的时候非常有用。 uiRealm.write({ () -> Void in uiRealm.deleteAll() }) 更新对象 在Realm中有很多方法可以实现对象的更新操作,但是所有的的这些方法都必须在一个写事务里面。下面我们将会看见其中的一些更新对象方法。 使用属性 你可以通过在写事务的闭包里对对象的属性的值进行重新设置来完成Realm对象的更新。例如,在TasksViewController中我们可以通过下面的方法来改变一个任务的完成状态: uiRealm.write({ () -> Void in task.isCompleted = true }) 使用主键 Realm支持使用一个字符串或者整型属性来作为对象的主键。当用户通过add()方法来创建新的Realm对象的时候,如果对象的键值以及存在,那么对象会被更新为一个新的值。下面是示例: let user = User() user.firstName = "John" user.lastName = "Smith" user.email = "example@example.com" user.id = 1 // Updating User with id = 1 realm.write { realm.add(user, update: true) } 上面的id属性是键值,如果已经存在一个id = 1的用户的时候,Realm会相应的更新该对象。否则直接插入。 使用KVC(Key-Value Coding) 如果你是一个有经验的iOS开发人员,你一定会对KVC很熟悉了。Realm中的Object、Results、List类都兼容KVC。该特性能让你在运行时设置更新属性。另一个非常好的特性是对于List、Results你可以以集合的方式批量进行更新,而无需迭代每一个来进行更新。可能你还不是很明白,看下面的例子: let tasks = uiRealm.objects(Task) uiRealm.write { () -> Void in tasks.setValue(true, forKeyPath: "isCompleted") } 在上面的代码中,我首先查询得到了所有任务对象然后将所有结果的isCompleted设置为了true。这意味着我只使用了一行代码就完成了对所有任务的完成标记。 我们再次回到ToDo app,在displayAlertToAddTaskList方法中你应该能够发现如下的代码片段: //update mode uiRealm.write({ () -> Void in updatedList.name = listName! self.readTasksAndUpdateUI() }) 该代码会在用户编辑list名称的时候执行。我们通过设置属性名来完成更新操作。 显示Tasks 我们已经看过了TaskListViewController中的绝大部份代码。现在我们来看下用于显示一个任务列表任务的TasksViewController。该视图控制器有一个UITableView,这个table view分为了两个部分:待完成和已完成任务。在TasksViewController中有如下属性: var selectedList : TaskList! var openTasks : Results! var completedTasks : Results! selectedList是通过TaskListsViewController传递过来的选择的任务链表。为了区分任务的完成状态,定义了两个变量openTasks、completedTasks。使用Realm的神奇函数filter()可以实现区分。在解释如何筛选前,先看下代码: func readTasksAndUpateUI(){ completedTasks = self.selectedList.tasks.filter("isCompleted = true") openTasks = self.selectedList.tasks.filter("isCompleted = false") self.tasksTableView.reloadData() } 在这个函数里面我们通过使用Realm提供的filter()方法涉嫌了结果的区分筛选。该方法能被 List、Result、Object实例进行调用,并根据设置的字符串条件返回我们期待的结果。你可以将该函数想象成NSPredicate,两个基本上是一样的功能。你也可以通过筛选条件创建NSPredicate来完成一样的功能。 下面是一个示例: //using predicate string var redCars = realm.objects(Car).filter("color = 'red' AND name BEGINSWITH 'BMW'") // using NSPredicate let aPredicate = NSPredicate(format: "color = %@ AND name BEGINSWITH %@", "red", "BMW") redCars = realm.objects(Car).filter(aPredicate) 在上面的代码中,我们筛选了那些红色并且名字以"BMW"开头的车。第一行和第二行代码筛选出来的结果是一样的。下面的表中列出了常用的筛选比较操作符: 排序 到目前为止我已经解释了Realm数据库的基本操作,在结束教程之前还有一个特征我想介绍给大家。排序是Realm提供的另一个非常有用的特性。在List、Result中你可以调用排序算法("sore criteria")对一组数据进行排序。下面我们看看如何使用字母或者创建时间来进行排序。首先我们在UI上添加一个segmented控件,排序会依据用户进行。 代码实现: @IBAction func didSelectSortCriteria(sender: UISegmentedControl) { if sender.selectedSegmentIndex == 0{ // A-Z self.lists = self.lists.sorted("name") } else{ // date self.lists = self.lists.sorted("createdAt", ascending:false) } self.taskListsTableView.reloadData() } 总结 Realm是一个简单直接的本地存储管理和数据库的解决方案。Realm让你只需要几行代码就能让代码变得可拓展型强、且简化了工作节省了时间。对于那些需要使用数据库的应用和公司来说,Realm真的很值得一试。 接下来要做的 这篇教程只是简单介绍了Realm的一些基本操作,例如Reading、Writing、Updating、Deletion。还有一些更高级的话题很值得你自己去探索学习,最好的方法就是去官方网站看官方文档。 整个演示的完整代码。 你可能感兴趣的:(ios,swift,realm) ArcGIS Runtime SDK for iOS 开发之地图范围(map extent) hlj184 ArcGISforIOSarcgisios开发mapextent 注:本篇文章翻译自:https://developers.arcgis.com/ios/objective-c/guide/iphonesdk-mapnavigation.htm;地图视图包含了地图范围被定义和改变的选项。值得注意的是,底图(加载到地图中的第一层图层)定义了下列地图属性:初始化范围全部范围空间参考系其中,初始范围可以被改变,而空间参考不可以改变。本篇文章主要讨论针对开发者和最终用户 Linux常用的命令一 Agome99 linux运维服务器 目录1.常用命令1.常用命令1)#与$提示的区别'#'表示用户有root权限,一般的以root用户登录提示符为#,'$'提示符表示用户为普通用户2)ifconfig查看ip地址eno1:代表由主板bios内置的网卡ens1:代表主板bios内置的PCI_E网卡enp2s0:PCI-E独立网卡eth0:如果以上都不用,则返回默认的网卡名ens33则属于第二种类型,即说明你的网卡是内置的PCI-E网卡 flutter pigeon gomobile 插件中使用go工具类 yujunlong3919 fluttergolangswiftkotlin 文章目录为什么flutter要用go写工具类1.下载pigeon插件模版2.编写go代码3.生成greeting.aar,Greeting.xcframework4.ios5.android6.dart中使用为什么flutter要用go写工具类在Flutter应用中,有些场景涉及到大量的计算,比如复杂的加密算法、数据压缩/解压缩或者图形处理中的数学计算等1.下载pigeon插件模版base_plu 教程分享:手机应用自动化 QH_ShareHub 自动化运维 手机应用程序的自动化通常涉及使用专门设计的自动化框架和工具。对于Android和iOS平台,以下是一些常用的自动化工具:Android:Espresso:Espresso是谷歌官方支持的自动化测试框架。它适用于写UI测试来模拟用户对Android应用的交云。Espresso工作在应用程序的内存中,因此能够快速执行。UIAutomator:这个框架允许测试者创建自动化脚本来检测和操作用户界面元素。它 iOS blocks - 三個會造成retain cycle的anti patterns backapace blockretaincycleiOSiOSblockretaincycle 在iOS4.0推出了Blocks這個語言特性後到現在iOS都已經出到5.0了所以我想Blocks應該可以被廣泛應用了但現在iOS環境是從MRC(ManualReferenceCounting)走到ARC(AutomaticReferenceCounting)在ReferenceCounting的環境中Runtime是無法自動解除Retaincycle的而Blocks有很多隱性的retain的動作很 iOS Blocks与Dispatch Queue的使用 a14776584 IOSBlocksDispatchQueuedispatch_asynciosiOSIOS 转载自http://liwpk.blog.163.com/blog/static/363261702012413103111749/block是什么block是一个Clevel的语法以及运行时的一个特性,和标准C中的函数(函数指针)类似。用于回调函数的地方。两个对象间的通讯。实现轻量级的“代理”。blocks和C语言函数指针的区别如何调用blocks调用block和C语言函数指针的调用一模一样如何 IOS Blocks Rainbow_Me iosreference存储c 在ios,blocks是对象,它封装了一段代码,这段代码可以在任何时候执行。Blocks可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它和传统的函数指针很类似,但是有区别:blocks是inline的,并且它对局部变量是只读的。1.Blocks的定义:int(^Multiply)(int,int)=^(intnum1,intnum2){returnnum1*num2;};定义 Linux运维常见问题排查 Hadesls Linux1024程序员节 1.Linux系统安装初始状态时>找不到硬盘,无法进入下一步安装解决方法:进入BIOS/COMS设置,找到硬盘设置相关选项,并设置为兼容模式。2.Linux系统安装时,在硬盘分区完成后>无法继续安装解决方法:硬盘分区不符合安装要求,可能忘记创建根分区或swap交换分区。这一点与Windows系统安装有区别。3.Linux系统安装时,软件包选择困惑,安装完成后发现有组件未按需求安装;解决方法:对Li 拔河 24蓝桥省b 亿秒签到 算法 #includeusingnamespacestd;#defineintlonglong#defineendl'\n'signedmain(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);intn;cin>>n;vectora(n+1);multisets;for(inti=1;i>a[i],a[i]=a[i-1]+a[i];for(inti=1; Linux系统性能调优技巧 敖光 SRE devopslinux运维服务器 Linux系统性能调优需要结合硬件资源、业务场景和系统瓶颈进行针对性优化。以下是系统化的调优思路和常用技巧,涵盖CPU、内存、磁盘、网络、内核参数等核心方向:一、性能分析工具速查工具用途示例命令top/htop实时监控进程CPU、内存占用htop-d10vmstat查看内存、进程、CPU上下文切换vmstat15iostat监控磁盘I/O和吞吐量iostat-x1sar历史性能数据收集(需安装sy 教程 | Ventoy全攻略:2025最新安装与使用教程,打造万能多系统启动盘 The god of big data 教程神器?三叉戟?虚拟系统系统架构 一、Ventoy简介与核心优势Ventoy是一款开源免费的多系统启动盘工具,支持Windows、Linux、macOS等操作系统及各类维护工具。其最大特点是无需反复格式化U盘,只需将ISO/WIM/IMG等镜像文件直接拷贝至U盘即可启动,且支持LegacyBIOS与UEFI双模式。相较于传统工具,Ventoy的优势包括:多系统兼容性:支持超1000种ISO镜像,涵盖主流操作系统及工具(如Windo vue 的axios请求数据2种方式 很重要 缘飞梦 vue前端技术vueaxios请求数据的方法 show:function(){//post方式//赋值给变量self//使用axios请求后台的数据get和post的两种方式varself=this;varurl='xxxx.json';axios.post(url,{params:{username:"yyyyy",password:'18888'}}).then(function(response){console.log(respons js小程序ios日期解析失败NAN兼容 wapchief 前端技术javascript开发语言ecmascript 小程序中ios使用newDate()的时候,如果有“-”分隔符,将会解析失败如果日期过短也会解析失败,比如只有2022-08,年月这样也解析不出来,下面工具能解决上述问题,但是在手动创建字符串时间,建议使用2022/08/01,斜杠等方式,需要组件展示的时候再用工具转换format(date,fmt){if(typeofdate==='string'){//ios解析不出来年月2020-05if( iOS开发书籍推荐 - 《高性能 iOS应用开发》(附带链接) 胖虎1 开发经验分享iosiOS开发iOS高性能iOS高级iOS进阶 引言在iOS开发的过程中,随着应用功能的增加和用户需求的提升,性能优化成为了不可忽视的一环。尤其是面对复杂的界面、庞大的数据处理以及不断增加的后台操作,如何确保应用的流畅性和响应速度,成为开发者的一大挑战。《高性能iOS应用开发》这本书正是为了解决这些问题,提供了深入的性能优化指导。这本书不仅涵盖了从应用启动到界面渲染、从内存管理到多线程处理的各个性能优化方面,还通过具体的案例和实用的技巧,帮助开 超详细教程:手把手教你在 App Store 添加内购功能(从零开始到上线)” “新手必看!一文搞定 iOS 内购功能:完整步骤与代码解析” “不懂代码也能看懂!带你逐步实现 App 内购(In-Ap 南北极之间 web前端特效源码ios前端javascript苹果支付苹果商店虚拟支付苹果虚拟支付 目录什么是内购功能(In-AppPurchase)?实现内购功能前的准备工作(1)启用内购功能的前置条件(2)创建AppID并启用内购权限在AppStoreConnect中添加内购项目(1)内购类型的选择与区别(2)创建内购商品并填写相关信息使用代码实现内购功能测试内购功能(1)创建沙盒测试账号(2)如何在设备中登录测试账号提交审核总结与常见问题解答1.什么是内购功能(In-AppPurchase 探索水平视界:Horizon SDK for iOS深度解析与应用推荐 杭律沛Meris 探索水平视界:HorizonSDKforiOS深度解析与应用推荐去发现同类优质开源项目:https://gitcode.com/项目介绍在数字时代的洪流中,视频录制与摄影已不仅仅是捕捉瞬间的艺术,它更是技术创新的前沿阵地。HorizonSDKforiOS,一个旨在颠覆传统视频记录体验的库,以其独特的实时水平校正算法和强大的定制滤镜功能,成为iOS开发者的新宠。通过这个开源项目,开发者能够轻松地为自 iOS App的启动与优化 Cedicn IOS开发ios App的启动流程App启动分为冷启动和热启动冷启动:从0开始启动App热启动:App已经在内存中,但是后台还挂着,再次点击图标启动App。一般对App启动的优化都是针对冷启动。App冷启动可分为三个阶段:dyld:加载镜像、动态库RunTime方法main函数初始化动态库vs静态库静态库:一堆.o文件的集合(通常是.a后缀),还没有被链接过,缺点是产物体积比较大,优点是链接到App之后体积比较小。 使用pydub库操作与二进制音频数据互转 文子阳 python音视频ffmpeg 一、二进制数据转AudioSegment对象binary_data=b'...'#二进制音频数据combined_audio=AudioSegment.from_file(io.BytesIO(binary_data))二、AudioSegment对象转二进制数据binary_data=b'...'#二进制音频数据combined_audio=AudioSegment.from_file(io.B Flutter学习 T_yoo_csdn Flutter前端Flutter flutter环境搭建mac版Flutter中文网Flutter原理及美团的实践背景Flutter的目标是使同一套代码同时运行在Android和iOS系统上,并且拥有媲美原生应用的性能,Flutter甚至提供了两套控件来适配Android和iOS(滚动效果、字体和控件图标等等),为了让App在细节处看起来更像原生应用。在Flutter诞生之前,已经有许多跨平台UI框架的方案,比如基于WebView 深入解析 iOS 视频录制(一):录制管理核心MWRecordingController 类的设计与实现 胖虎1 媒体捕捉开发经验分享音视频音视频录制自定义录制AVFoundation 深入解析iOS视频录制(一):录制管理核心MWRecordingController类的设计与实现深入解析iOS视频录制(二):自定义UI的实现深入解析iOS视频录制(三):完整录制流程的实现与整合引言在iOS应用开发中,视频录制功能越来越常见,尤其是在直播、短视频和社交应用中,用户经常需要录制高质量的视频内容。为了实现这个功能,我们不仅需要处理视频的输入和输出,还要控制摄像头的切换、录制的开始与 iOS 获取设备占用内存 Johnny Tong iOS之旅ios内存HOST_VM 获取应用占用内存获取应用进程占用内存-(NSUInteger)memoryUsage{task_vm_info_data_tvmInfo;mach_msg_type_number_tcount=TASK_VM_INFO_COUNT;kern_return_tresult=task_info(mach_task_self(),TASK_VM_INFO,(task_info_t)&vmInfo,&co iOS 中使用 FFmpeg 的高级功能 - 滤镜(Filters) 陈皮话梅糖@ FFmpeg音视频高阶技术讲解iosffmpeg FFmpeg提供了强大的滤镜功能,可以对音视频进行各种处理,例如裁剪、缩放、添加水印、调整颜色、添加特效等。1.FFmpeg滤镜基础知识1.1什么是滤镜(Filters)?滤镜是FFmpeg提供的一种功能,用于对音视频流进行处理。滤镜链(FilterChain)是多个滤镜的组合,按顺序对输入流进行处理。滤镜图(FilterGraph)是一个复杂的滤镜链,可以包含多个输入和输出。1.2常见的滤镜滤镜 Unity游戏icon 木雁之 游戏androidiosunity 图片格式,统一为PNG格式文章目录iOSiconAndroidiconAndroid8.0以下(API25andbelow)的版本Android8.0及以上(API26andabove)的版本iOSiconiOS平台icon资源,规格如下:文件名尺寸ICON_20.png20x20ICON_29.png29x29ICON_40.png40x40ICON_58.png58x58ICON_60.png 软件测试技术之跨平台的移动端UI自动化测试(上) 学掌门 软件测试ITui软件测试 摘要:本文提出一种跨平台的UI自动化测试方案,一方面使用像素级的截图对比技术,解决传统UI自动化测试难以验证页面样式的问题;另一方面用统一部署在服务器端的JavaScript测试代码代替Android和iOS测试代码,大大提高编写测试代码的效率。该方案经过实际验证,具有效率高、质量好、便于维护等多方面优点,文中将阐述具体设计思路以及各关键步骤的实现方法,为同类测试提供借鉴。一、背景当前金融服务数字 ios 小程序 虚拟商品支付怎么解 rock——you 前端ios小程序cocoa 在iOS小程序中涉及虚拟商品支付的问题需要特别注意,因为苹果AppStore的审核规则(AppStoreReviewGuidelines)对虚拟商品的支付有严格的规定,任何涉及虚拟商品的支付必须使用苹果的IAP(In-AppPurchase)支付。以下是解决iOS小程序虚拟商品支付的思路和常见的合规方案:苹果的政策背景根据AppStore审核指南的规定:虚拟商品的支付:涉及虚拟商品或服务(如会员订 QEMU-Manager:Mac上的QEMU图形化管理利器 苏承根 QEMU-Manager:Mac上的QEMU图形化管理利器项目地址:https://gitcode.com/gh_mirrors/qe/QEMU-Manager在探索虚拟化的浩瀚世界时,找到一个既强大又易用的工具至关重要。今天,我们要向您隆重推荐QEMU-Manager——一款专为macOS设计的QEMU图形前端,由Swift语言精心打造。通过这篇文章,我们将深入挖掘QEMU-Manager的魅力 掌握iOS导航控制器实践指南.zip 滚菩提哦呢 本文还有配套的精品资源,点击获取简介:在iOS开发中,导航控制器是一个核心组件,用于管理视图控制器的导航堆栈,提供用户界面的“前进/后退”导航体验。本压缩包提供了一系列示例和代码片段,讲解了如何使用导航控制器以及如何利用XIB文件来设计和实现视图控制器的界面。开发者将通过这些实践示例学习到导航控制器的工作原理和基本操作,包括视图控制器的推送、弹出,以及如何访问和操作导航栈。这些知识对于创建流畅直观 ios中常见的设计原则和设计模式 没头脑的ht 设计模式 七大设计原则1:开闭原则对扩展开放,对修改关闭,在设计模块的时候,使模块在不被修改的前提下可以扩展功能2:依赖倒置原则实现尽量依赖抽象,不依赖具体实现(1)高层模块不应该依赖底层模块,两者都应该依赖于抽象(2)抽象不应该依赖于细节,细节应该依赖于抽象3:单一职责原则对于一个类而言,应该只存在一个可以一起类变化的原因,一个类只承担一个职责,如果一个类有两个职责,应该将其非开。比如tableviewC 备战蓝桥杯 Day4 差分 爱coding的橙子 蓝桥杯蓝桥杯算法c++ 差分(修改区间后查询)1.要点a[0]=0;for(inti=1;iusingnamespacestd;typedeflonglongll;constintN=1e5+9;lla[N],b[N],bdiff[N];//b[N]为位置查询次数数组.bdiff[N]为位置查询次数差分数组intmain(){ios::sync_with_stdio(false),cin.tie(0),cout.tie( ffmpeg 多路流处理在iOS的具体使用 陈皮话梅糖@ FFmpeg音视频高阶技术讲解ffmpegios 多路流处理可以用于操作音视频文件中的多个流(如视频流、音频流、字幕流等),实现流的提取、替换、合并等操作。1.什么是多路流处理?1.1多路流的概念一个多媒体文件(如MP4、MKV)通常包含多个流:视频流:存储视频数据。音频流:存储音频数据。字幕流:存储字幕数据。FFmpeg提供了强大的工具来操作这些流,例如提取、替换、合并等。1.2常见的多路流操作操作类型功能描述提取流从文件中提取特定的流(如音频 jvm调优总结(从基本概念 到 深度优化) oloz javajvmjdk虚拟机应用服务器 JVM参数详解:http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html Java虚拟机中,数据类型可以分为两类:基本类型和引用类型。基本类型的变量保存原始值,即:他代表的值就是数值本身;而引用类型的变量保存引用值。“引用值”代表了某个对象的引用,而不是对象本身,对象本身存放在这个引用值所表示的地址的位置。 【Scala十六】Scala核心十:柯里化函数 bit1129 scala 本篇文章重点说明什么是函数柯里化,这个语法现象的背后动机是什么,有什么样的应用场景,以及与部分应用函数(Partial Applied Function)之间的联系 1. 什么是柯里化函数 A way to write functions with multiple parameter lists. For instance def f(x: Int)(y: Int) is a HashMap dalan_123 java HashMap在java中对很多人来说都是熟的;基于hash表的map接口的非同步实现。允许使用null和null键;同时不能保证元素的顺序;也就是从来都不保证其中的元素的顺序恒久不变。 1、数据结构 在java中,最基本的数据结构无外乎:数组 和 引用(指针),所有的数据结构都可以用这两个来构造,HashMap也不例外,归根到底HashMap就是一个链表散列的数据 Java Swing如何实时刷新JTextArea,以显示刚才加append的内容 周凡杨 java更新swingJTextArea 在代码中执行完textArea.append("message")后,如果你想让这个更新立刻显示在界面上而不是等swing的主线程返回后刷新,我们一般会在该语句后调用textArea.invalidate()和textArea.repaint()。 问题是这个方法并不能有任何效果,textArea的内容没有任何变化,这或许是swing的一个bug,有一个笨拙的办法可以实现 servlet或struts的Action处理ajax请求 g21121 servlet 其实处理ajax的请求非常简单,直接看代码就行了: //如果用的是struts //HttpServletResponse response = ServletActionContext.getResponse(); // 设置输出为文字流 response.setContentType("text/plain"); // 设置字符集 res FineReport的公式编辑框的语法简介 老A不折腾 finereport公式总结 FINEREPORT用到公式的地方非常多,单元格(以=开头的便被解析为公式),条件显示,数据字典,报表填报属性值定义,图表标题,轴定义,页眉页脚,甚至单元格的其他属性中的鼠标悬浮提示内容都可以写公式。 简单的说下自己感觉的公式要注意的几个地方: 1.if语句语法刚接触感觉比较奇怪,if(条件式子,值1,值2),if可以嵌套,if(条件式子1,值1,if(条件式子2,值2,值3) linux mysql 数据库乱码的解决办法 墙头上一根草 linuxmysql数据库乱码 linux 上mysql数据库区分大小写的配置 lower_case_table_names=1 1-不区分大小写 0-区分大小写 修改/etc/my.cnf 具体的修改内容如下: [client] default-character-set=utf8 [mysqld] datadir=/var/lib/mysql socket=/va 我的spring学习笔记6-ApplicationContext实例化的参数兼容思想 aijuans Spring 3 ApplicationContext能读取多个Bean定义文件,方法是: ApplicationContext appContext = new ClassPathXmlApplicationContext( new String[]{“bean-config1.xml”,“bean-config2.xml”,“bean-config3.xml”,“bean-config4.xml mysql 基准测试之sysbench annan211 基准测试mysql基准测试MySQL测试sysbench 1 执行如下命令,安装sysbench-0.5: tar xzvf sysbench-0.5.tar.gz cd sysbench-0.5 chmod +x autogen.sh ./autogen.sh ./configure --with-mysql --with-mysql-includes=/usr/local/mysql sql的复杂查询使用案列与技巧 百合不是茶 oraclesql函数数据分页合并查询 本片博客使用的数据库表是oracle中的scott用户表; ------------------- 自然连接查询 查询 smith 的上司(两种方法) & 深入学习Thread类 bijian1013 javathread多线程java多线程 一. 线程的名字 下面来看一下Thread类的name属性,它的类型是String。它其实就是线程的名字。在Thread类中,有String getName()和void setName(String)两个方法用来设置和获取这个属性的值。 同时,Thr JSON串转换成Map以及如何转换到对应的数据类型 bijian1013 javafastjsonnet.sf.json 在实际开发中,难免会碰到JSON串转换成Map的情况,下面来看看这方面的实例。另外,由于fastjson只支持JDK1.5及以上版本,因此在JDK1.4的项目中可以采用net.sf.json来处理。 一.fastjson实例 JsonUtil.java package com.study; impor 【RPC框架HttpInvoker一】HttpInvoker:Spring自带RPC框架 bit1129 spring HttpInvoker是Spring原生的RPC调用框架,HttpInvoker同Burlap和Hessian一样,提供了一致的服务Exporter以及客户端的服务代理工厂Bean,这篇文章主要是复制粘贴了Hessian与Spring集成一文,【RPC框架Hessian四】Hessian与Spring集成 在 【RPC框架Hessian二】Hessian 对象序列化和反序列化一文中 【Mahout二】基于Mahout CBayes算法的20newsgroup的脚本分析 bit1129 Mahout #!/bin/bash # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information re nginx三种获取用户真实ip的方法 ronin47 随着nginx的迅速崛起,越来越多公司将apache更换成nginx. 同时也越来越多人使用nginx作为负载均衡, 并且代理前面可能还加上了CDN加速,但是随之也遇到一个问题:nginx如何获取用户的真实IP地址,如果后端是apache,请跳转到<apache获取用户真实IP地址>,如果是后端真实服务器是nginx,那么继续往下看。 实例环境: 用户IP 120.22.11.11 java-判断二叉树是不是平衡 bylijinnan java 参考了 http://zhedahht.blog.163.com/blog/static/25411174201142733927831/ 但是用java来实现有一个问题。 由于Java无法像C那样“传递参数的地址,函数返回时能得到参数的值”,唯有新建一个辅助类:AuxClass import ljn.help.*; public class BalancedBTree { BeanUtils.copyProperties VS PropertyUtils.copyProperties 诸葛不亮 PropertyUtilsBeanUtils BeanUtils.copyProperties VS PropertyUtils.copyProperties 作为两个bean属性copy的工具类,他们被广泛使用,同时也很容易误用,给人造成困然;比如:昨天发现同事在使用BeanUtils.copyProperties copy有integer类型属性的bean时,没有考虑到会将null转换为0,而后面的业 [金融与信息安全]最简单的数据结构最安全 comsci 数据结构 现在最流行的数据库的数据存储文件都具有复杂的文件头格式,用操作系统的记事本软件是无法正常浏览的,这样的情况会有什么问题呢? 从信息安全的角度来看,如果我们数据库系统仅仅把这种格式的数据文件做异地备份,如果相同版本的所有数据库管理系统都同时被攻击,那么 vi区段删除 Cwind linuxvi区段删除 区段删除是编辑和分析一些冗长的配置文件或日志文件时比较常用的操作。简记下vi区段删除要点备忘。 vi概述 引文中并未将末行模式单独列为一种模式。单不单列并不重要,能区分命令模式与末行模式即可。 vi区段删除步骤: 1. 在末行模式下使用:set nu显示行号 非必须,随光标移动vi右下角也会显示行号,能够正确找到并记录删除开始行 清除tomcat缓存的方法总结 dashuaifu tomcat缓存 用tomcat容器,大家可能会发现这样的问题,修改jsp文件后,但用IE打开 依然是以前的Jsp的页面。 出现这种现象的原因主要是tomcat缓存的原因。 解决办法如下: 在jsp文件头加上 <meta http-equiv="Expires" content="0"> <meta http-equiv="kiben&qu 不要盲目的在项目中使用LESS CSS dcj3sjt126com Webless 如果你还不知道LESS CSS是什么东西,可以看一下这篇文章,是我一朋友写给新人看的《CSS——LESS》 不可否认,LESS CSS是个强大的工具,它弥补了css没有变量、无法运算等一些“先天缺陷”,但它似乎给我一种错觉,就是为了功能而实现功能。 比如它的引用功能 ? .rounded_corners{ [入门]更上一层楼 dcj3sjt126com PHPyii2 更上一层楼 通篇阅读完整个“入门”部分,你就完成了一个完整 Yii 应用的创建。在此过程中你学到了如何实现一些常用功能,例如通过 HTML 表单从用户那获取数据,从数据库中获取数据并以分页形式显示。你还学到了如何通过 Gii 去自动生成代码。使用 Gii 生成代码把 Web 开发中多数繁杂的过程转化为仅仅填写几个表单就行。 本章将介绍一些有助于更好使用 Yii 的资源: Apache HttpClient使用详解 eksliang httpclienthttp协议 Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送Http请求变得容易,而且也方便了开发人员测试接口(基于Http协议的),即提高了开发的效率,也方便提高代码的健壮性。因此熟练掌握HttpClient是很重要的必修内容,掌握HttpClient后,相信对于Http协议的了解会 zxing二维码扫描功能 gundumw100 androidzxing 经常要用到二维码扫描功能 现给出示例代码 import com.google.zxing.WriterException; import com.zxing.activity.CaptureActivity; import com.zxing.encoding.EncodingHandler; import android.app.Activity; import an 纯HTML+CSS带说明的黄色导航菜单 ini htmlWebhtml5csshovertree HoverTree带说明的CSS菜单:纯HTML+CSS结构链接带说明的黄色导航 在线体验效果:http://hovertree.com/texiao/css/1.htm代码如下,保存到HTML文件可以看到效果: <!DOCTYPE html > <html > <head> <title>HoverTree fastjson初始化对性能的影响 kane_xie fastjson序列化 之前在项目中序列化是用thrift,性能一般,而且需要用编译器生成新的类,在序列化和反序列化的时候感觉很繁琐,因此想转到json阵营。对比了jackson,gson等框架之后,决定用fastjson,为什么呢,因为看名字感觉很快。。。 网上的说法: fastjson 是一个性能很好的 Java 语言实现的 JSON 解析器和生成器,来自阿里巴巴的工程师开发。 基于Mybatis封装的增删改查实现通用自动化sql mengqingyu DAO 1.基于map或javaBean的增删改查可实现不写dao接口和实现类以及xml,有效的提高开发速度。 2.支持自定义注解包括主键生成、列重复验证、列名、表名等 3.支持批量插入、批量更新、批量删除 <bean id="dynamicSqlSessionTemplate" class="com.mqy.mybatis.support.Dynamic js控制input输入框的方法封装(数字,中文,字母,浮点数等) qifeifei javascript js 在项目开发的时候,经常有一些输入框,控制输入的格式,而不是等输入好了再去检查格式,格式错了就报错,体验不好。 /** 数字,中文,字母,浮点数(+/-/.) 类型输入限制,只要在input标签上加上 jInput="number,chinese,alphabet,floating" 备注:floating属性只能单独用*/ funct java 计时器应用 tangqi609567707 javatimer mport java.util.TimerTask; import java.util.Calendar; public class MyTask extends TimerTask { private static final int erlang输出调用栈信息 wudixiaotie erlang 在erlang otp的开发中,如果调用第三方的应用,会有有些错误会不打印栈信息,因为有可能第三方应用会catch然后输出自己的错误信息,所以对排查bug有很大的阻碍,这样就要求我们自己打印调用的栈信息。用这个函数:erlang:process_display (self (), backtrace).需要注意这个函数只会输出到标准错误输出。 也可以用这个函数:erlang:get_s 按字母分类: ABCDEFGHIJKLMNOPQRSTUVWXYZ其他