首页 文章 精选 留言 我的

精选列表

搜索[企业级],共10000篇文章
优秀的个人博客,低调大师

企业级 SpringBoot 教程-sprinboot整合elk,搭建实时日志平台

elk 简介 Elasticsearch是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。 Logstash是一个完全开源的工具,他可以对你的日志进行收集、过滤,并将其存储供以后使用(如,搜索)。 Kibana 也是一个开源和免费的工具,它Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助您汇总、分析和搜索重要数据日志。 elk下载安装 elk下载地址:https: //www. elastic. co/downloads/ 建议在 linux上运行,elk在windows上支持得不好,另外需要jdk1.8 的支持,需要提前安装好jdk. 下载完之后: 安装,以logstash为例子: cd /usr/local/ mkdir logstash tar -zxvf logstash-5.3.2.tar.gz mv logstash-5.3.2 /usr/local/logstash 配置、启动 Elasticsearch 打开Elasticsearch的配置文件: vim config/elasticsearch.yml 修改配置: network.host=localhost network.port=9200 它默认就是这个配置,没有特殊要求,在本地不需要修改。 启动Elasticsearch ./bin/elasticsearch 启动成功,访问localhost:9200,网页显示: { "name" : "56IrTCM", "cluster_name" : "elasticsearch", "cluster_uuid" : "e4ja7vS2TIKI1BsggEAa6Q", "version" : { "number" : "5.2.2", "build_hash" : "f9d9b74", "build_date" : "2017-02-24T17:26:45.835Z", "build_snapshot" : false, "lucene_version" : "6.4.1" }, "tagline" : "You Know, for Search" } 配置、启动 logstash 在 logstash的主目录下: vim config/log4j_to_es.conf 修改 log4j_to_es.conf 如下: input { log4j { mode => "server" host => "localhost" port => 4560 } } filter { #Only matched data are send to output. } output { elasticsearch { action => "index" #The operation on ES hosts => "localhost:9200" #ElasticSearch host, can be array. index => "applog" #The index to write data to. } }Spring Cloud大型企业分布式微服务云架构源码一七九一七四三三八零哦 修改完配置后启动: ./bin/logstash -f config/log4j_to_es.conf

优秀的个人博客,低调大师

企业级分布式应用服务EDAS评测报告

一、测试产品背景: EDAS 是一个围绕应用和微服务的PaaS平台,提供多样的应用发布和轻量级微服务解决方案,帮助用户解决在应用和服务管理过程中监控、诊断和高可用运维问题;提供Spring Cloud和Dubbo的运行环境。根据阿里云官方文档的信息,EDAS是一个面向企业提供分布式应用服务的中间件产品,支持的框架环境为SPRING CLOUD和DUBBO,去除不同版本所提供的增值服务的差异,整个产品提供的核心服务包括以下几个方面:1、 微服务:可以采用SPRING CLOUD或DUBBO开发应用,EDAS提供分布式配置推送和分布式任务调度服务。2、 对系统和服务的状况提供的实时监控服务。3、 应用的生命周期管理。4、 实时日志。5、 基于阿里云计算的弹性伸缩服务。6、 持续集成。7、 离线配

优秀的个人博客,低调大师

微软企业级加解密解决方案MBAM用户和组

部署独立模式架构,我准备了5台计算机,分别是DC、MBAMSQL、MBAM、2台Win8.1 DC我就不多说了,域控角色,当然我的DC上也承载了我的CA角色 第一部,我们需要在AD中创建如下用户和组: MBAMSQL是我的数据库角色,数据库我采用的是SQL2012,但需要注意的是必须安装采用 SQL_Latin1_General_CP1_CI_AS 排序规则,MBAMSQL所需权限: ? SQL Server 实例登录服务器角色:dbcreator和processadmin ? SQL Server Reporting Services 实例权限:创建文件夹和发布报告 MBAM就是我们的管理服务器,承载了MBAM的管理员站点和用户自助门户站点。 本文转自 ZJUNSEN 51CTO博客,原文链接:http://blog.51cto.com/rdsrv/1926601,如需转载请自行联系原作者

优秀的个人博客,低调大师

《企业级ios应用开发实战》一2.4 搭建iOS开发环境

2.4 搭建iOS开发环境 迄今为止,iOS只支持在苹果的Mac OSX操作系统下进行开发。因此,对于大部分开发者而言,一台基于Intel的苹果电脑仍然是必需的——无论是Mac Book还是Mac Mini都能满足开发的需要。当然,也可以在非苹果的电脑上安装Mac OS X,正如下面介绍的,借助于硬件虚拟化技术的支持,可以在虚拟机中安装Mac OS X。此外,需要下载并安装苹果的iOS开发工具包(Software Development Kit,SDK)。这是一个应用程序集合,包括了用于创建iOS应用程序所必需的IDE、API库及实用工具。最后,你可能需要在苹果官方网站进行注册。虽然这不是必需的,但如果不这样做的话,你可能无法将你的程序安装到设备上运行。 2.4.1 安装Mac OS X操作系统 自从2007年年底苹果公司正式发布代号为Leopard的Mac OS X 10.5开始,一种叫做“Hacked Apple”——把Mac OS安装到PC上的技术就成为了现实。仅仅在Leopard正式上市后的第二天就有高手将其成功破解,使用几个补丁文件便能让Leopard安装到普通的电脑上。由于Mac OS X本身对PC硬件的支持十分有限,在普通PC和笔记本电脑上安装Hacked Apple极其不易。尽管网络上存在有各种破解补丁、硬件驱动,甚至破解好的镜像文件,要想在一台非苹果电脑上“啃”一嘴苹果仍然是被戏称为“拼人品”,网上有着无数失败的先例。 有鉴于此,笔者并不建议初学者在非苹果PC上安装Mac OS X操作系统,与浪费了的无数精力和时间相比,所获得的好处实在不足以称道。如果实在是无法接受苹果电脑的高端价格,那么你可以尝试另一种在PC上安装Mac系统的方式——在虚拟机中安装——幸好我们还有虚拟机,无论是VMWare,还是VirtualBox。在虚拟机中安装Mac拥有以下好处:在Windows系统和Mac系统间切换不需要重启;在虚拟机中安装避免了硬件驱动不支持的问题,因为不需要安装硬件驱动程序;使用虚拟机安装有更高的成功率。以下以笔者的华硕X42J笔记本为例,演示如何在VirtualBox中安装Mac Snow Leopard OS X 10.6.5(支持i3/i5/i7)。1.推荐硬件配置原则上,CPU必须支持SSE2/SSE3和硬件虚拟技术。如果不能确定CPU是否支持硬件虚拟,可以运行SecurAble进行测试,出现如图2-4所示的对话框即为支持。以下列出笔者的笔记本硬件配置,以供参考:电脑型号——华硕K42JE笔记本电脑处理器——英特尔 Core i3 M350 @ 2.27GHz 笔记本处理器主板——华硕 K42JE(英特尔 HM55 芯片组)内存——2GB(海力士 DDR3 1333MHz) 主硬盘——希捷 ST9320423AS(320 GB / 7200 转/分)显卡——ATI Mobility Radeon HD 5470(512 MB)光驱——日立-LG DVDRAM GT32N DVD刻录机声卡——瑞昱 ALC269 @ 英特尔 5 Series/3400 Series Chipset网卡——智微 JMC25X PCI Express Gigabit Ethernet Adapter 2.准备使用的工具虚拟机Virtual Box的下载地址:http://u.115.com/file/t54cd05734。破解版的Mac OS X,iAntares OSx86 10.6.5 v3.2 繁简英整合版(2010年12月12日更新),下载地址:http://www.ed2000.com/ShowFile.asp?FileID=255645。3.安装过程打开Virtual Box,点击工具栏上的“新建”按钮,弹出“新建虚拟电脑”向导,选择操作系统类型为Mac OS X及Mac OS X Server,并为虚拟机设置一个名称(比如Snow Leopard),如图2-5所示。 点击“下一步”按钮,设置虚拟机使用的物理内存,请至少选择1GB(如图2-6所示)。 在选择虚拟磁盘时,选择“创建新的虚拟硬盘”。为了取得更好的性能,虚拟硬盘类型选择“固定大小”(如图2-7所示)。 虚拟硬盘容量至少设定为30GB,并保证文件存放位置的可用空间是足够的(如图2-8所示)。 点击“下一步”按钮,直至安装结束。选择刚才创建的虚拟机Snow Leopard,点击工具栏中的“设置”按钮,在弹出的虚拟机设置窗口左侧面板中选中“系统”,“启动顺序”选择“光驱、硬盘”,然后取消“启用EFI”选项,如图2-9所示。 选择左面板中“显示”项,将“显存大小”调为最大,然后选择“启动3D加速”选项(如图2-10所示)。 好的,虚拟机配置完成了,下面的步骤是安装Snow Leopard。在虚拟机设置窗口中,选择Storage,在IDE控制器中添加一个虚拟光驱,然后为这个虚拟光驱添加一个盘片,把iAntares OSx86 10.6.5 v3.2的iso文件镜像加载进去(如图2-11所示)。关闭设置窗口,双击虚拟机Snow Leopard启动虚拟机。如果顺利,虚拟机会用iAntares_v3.iso进行引导,并进入Snow Leopard的安装界面。选取中文作为安装语言,然后从菜单“实用工具”中打开“磁盘工具”。 在磁盘工具点击标签栏的“抹掉”,对磁盘进行格式化。文件系统格式为Mac OS扩展(日志式),然后点击按钮“抹掉”按钮(如图2-12所示)。 格式化完成后,选择格式化的磁盘作为安装目标,同时点击“自定”按钮。在接下来的自定义安装界面中,“启动选项”除了后面3项以外全部选中,硬件驱动全部不需要选(虚拟机已经带硬件驱动),引导器选择变色龙RC4 r684而不是RC5 r653,其余选项随意设置或保持默认值(如图2-13所示)。这个步骤是整个安装中最重要的步骤,也许需要尝试很多次才知道最适合机器的设置。这个过程中需要不断地修改启动选项并重启,甚至可能会出现几次蓝屏。但在虚拟机中安装的好处就在于,除了出现蓝屏以外,都不需要按电源或Reset键,虚拟机重启的速度比硬启动要快许多。这个步骤完成后就是缓慢的安装进度了,这需要一些时间,请耐心等候。安装完成后,可能会出现“安装失败”的提示,不必惊慌,重启虚拟机后,会发现虚拟机引导菜单上多了一个snow leopard的引导选项,这个就是我们安装成功的Mac OS操作系统,另一个是安装光盘(如图2-14所示)。 用方向键把光标移动到snow leopard上,回车,变色龙开始从Mac OS进行引导。启动后进入Snow Leopard桌面。由于某些Bug,在这个桌面工具栏上会有3个图标显示为问号(如图2-15所示),当然如果为了美观,完全可以删除它们。需要注意的是,如果Mac提示安装版本更新,请不要轻易更新系统,否则你可能进不了系统。因为破解的Mac OS X系统对系统内核进行了修改,如果升级的话有可能导致系统文件再次被覆盖,导致系统无法正常引导。接下来需要下载iOS SDK,并在Mac下进行安装。 2.4.2 下载安装SDK 每一个在苹果网站上注册了iPhone开发人员计划的程序员,都可以登录到以下地址下载最新版本的iOS SDK这是一个几个GB(根据版本不同)的Mac安装镜像文件,里面包括如下内容:Xcode集成在SDK中一起发布,它支持苹果的Objective-C语言,也支持C和C++代码。我们将在第4章介绍它的使用。Interface Builder用于创建程序的GUI,它和Xcode集成在一起,也可以单独启动。在本书很多地方仍然使用了它,第5章将对Interface Builder进行介绍。iPhone模拟器可以在Mac中调试iOS应用程序,它的外观和真实的iPhone/iPad设备一模一样。使用它调试程序,比在真实设备中更方便快捷。在后面的章节中,会大量使用这个工具调试程序。Dashcode也是/Developer/Applications中的一部分,它是用于创建Web应用的优秀、极为精巧的图形开发环境,本书中不会使用到它。双击下载后的文件,把SDK安装到Mac上。接下来,创建我们的第一个iOS应用程序,以此检验我们的开发环境已配置成功。

优秀的个人博客,低调大师

《企业级ios应用开发实战》一1.1 什么是企业应用

1.1 什么是企业应用 iPhone开发是一个新兴的话题,对于“企业应用”和“非企业应用”,它并没有很清晰的划分。这里借用了传统意义上的企业应用概念,试图阐述清楚如何区分iOS企业应用,以及iOS企业应用的定义。 1.1.1 传统意义的企业应用 据IDC统计,在过去的10年中,全球企业在信息系统上一共投资18万亿美元。巨大的投资为企业建立了众多信息系统,以帮助企业进行内外部业务的处理和管理工作。根据METAGroup的统计,一家典型的大型企业平均拥有49个应用系统。虽然迄今为止,“企业应用”都没有一个明确的定义,笔者认为企业应用是企业环境中的特定系统,例如:ECS(电子商务系统),企业通过实施电子商务实现企业经营目标,电子商务系统提供了网上交易和管理等全过程的服务,如网上订购、网上支付、电子账户、服务传递、意见征询、业务管理等各项功能。ERP(企业资源规划)系统,指建立在信息技术基础上,以系统化的管理思想,为企业决策层及员工提供决策运行手段的管理平台。企业通过企业资源规划系统能实现企业供应链管理、精益制造、敏捷制造以及整个生产过程的计划、控制、采购、销售、成本核算的管理目标。CRM(客户关系管理)系统,企业利用信息技术(IT)和互联网技术实现对客户的整合营销,是以客户为核心的企业营销的技术实现和管理实现。客户关系管理注重的是与客户的交流,企业的经营是以客户为中心,而不是传统的以产品或以市场为中心。OA(办公自动化)系统,它是利用计算机技术提高办公效率,实现办公自动化处理的系统。它采用Internet/Intranet技术,和工作流的概念,使企业内部人员能方便快捷地共享信息,协同工作,提升日常办公的工作效率,并为企业的管理和决策提供帮助。DBS(数据库系统),是企业信息化的核心,负责整个企业在经营过程中的数据储存、共享和处理,为其他信息系统提供支撑。DW(数据仓库)是在数据库已经大量存在的情况下,为了进一步挖掘数据资源、为了决策需要而建设的数据仓库。数据仓库系统是一个信息处理平台,它从业务处理系统获得数据,并处理数据,从而获得战略信息。由此可见,只要是在企业信息化环境中运行的应用软件,都可以称为企业应用。 1.1.2 iOS 企业应用 根据摩根士丹利发布的全球互联网发展趋势报告(Mary Meeker 2010)显示:全球互联网发展趋势正在由PC-Internet向Mobile-Internet转变,手机在某种意义上已经主导着互联网的发展,移动互联网将带来很多新的商业机会。新兴的下一代互联网,即Mobile 2.0正在崛起,同样带来令人刺激的软件行业商业机会。此外,2008年底中国3G牌照正式发放,标志着移动通信3G时代终于来临。移动通信网络由2G/2.5G向3G的过渡,为移动互联网绑上了高速发展的助推器。对国内软件开发商而言,这意味着新的机遇和挑战产生了。根据工业和信息化部网站发布的数据(中国工业和信息化部 2010),随着中国电信3G用户数达到1000万、TD用户数达到1698万、中国联通3G用户数达到1166万,目前我国三家电信企业的3G用户数均过千万。截至10月底,我国3G用户数累计达到3864万,环比增长10.4%,同比增长295.7%,比2009年年底增长2538万,10月新增用户364.6万户。TD用户在3G用户中的占比达到43.9%。与传统的2G和2.5G网络相比,3G 网络带宽已高达300~600kb/s,比之512kb/s的ADSL也相差无几,因此诸多应用不再受到带宽限制,诸如:移动办公、个人应用、移动金融、GPS导航、视频通话,甚至是传统的企业应用CRM、ERP,也可能运行在手机上。2007年1月的Macworld年度大会上,苹果公司发布了令人期待已久的iPhone手机。iPhone将创新的移动电话、可触摸宽屏iPod以及具有桌面级电子邮件、网页浏览、搜索和地图功能的突破性因特网通信设备这三种产品完美地融为一体,引入了基于大型多触点显示屏和领先性新软件的全新用户界面,让用户用手指即可控制iPhone。iPhone还开创了移动设备软件尖端功能的新纪元,重新定义了移动电话的功能。全球互联网向移动互联网的迁移,3G网络的兴起,新一代智能手机产品尤其是 iPhone 在全球市场中受到热烈追捧,导致企业应用正呈现由传统internet/intranet 向移动网络/手机终端扩张的趋势。iOS 正是苹果公司为其创新性产品 iPhone 开发的新一代手机操作系统,iOS 企业应用的概念,也因此衍生而来。

优秀的个人博客,低调大师

《企业级ios应用开发实战》一3.2 面向对象的C

3.2 面向对象的C 从现在开始,我们开始介绍期待已久的Objective-C的面向对象特性。 3.2.1 类和对象 面向对象最重要的概念就是类。通过类,我们可以实现面向对象的两个主要特性:继承和聚合。在Cocoa框架中,NSObject是所有类的根类,其他所有类从此开始继承。1.类的定义类的定义在接口.h文件中进行,典型的类定义如下面的代码所示: @interface MyClass:NSObject { NSString name; NSArray array; ... } @property(nonatomic,retain)NSString name; @property(nonatomic,retain)NSArray array; -(id)initWithName:(NSString)string; ... @end 从上面的例子中,我们可以看出以下几点:类的定义由@interface开始,到@end结束;类名后面紧跟冒号和所继承的父类名;花括号中定义类的成员变量;属性由@property关键字声明;方法声明位于成员声明之后,@end之前。2.方法方法类似于函数,虽然形式上有区别,但仍然由返回值、方法名和参数列表构成。其中,返回值和参数的类型说明使用圆括号括住,方法名分为多个部分,有几个参数,方法名就被分成几个部分,每个部分都有一个冒号分隔,冒号后面才是参数类型和参数名。此外,方法一般由一个方法类型符(+号或者号)修饰,+号表示方法为类方法,号表示方法为实例方法。例如: -(id)initWithName:(NSString)string withArray:(NSArray)arr; 方法开头的号表示这是一个实例方法。实例方法和类方法不同,实例方法属于实例对象所拥有,必须通过类的实例来调用;而类方法属于类所有,它直接通过类来调用,甚至不需要创建实例对象(等同于C++/Java中的static方法)。这个方法有两个参数(数一数参数列表中冒号的个数,一个冒号代表一个参数),因此方法名由两部分组成,两个带冒号的单词:initWithName:和withArray:。记住,方法名实际上由“方法名+参数名”两部分构成。而参数名是后面带冒号的单词,如果该方法没有参数,则方法名仅包含第1部分(即只有方法名,而没有参数名)。而且方法的第1个参数的参数名就是方法名。因此有多少个参数,方法名就会由多少个带冒号的单词组成。记住这一点,因为这跟现存的许多语言都不一样。在Objective-C中,总是用initWithName: withArray: 这样的形式表示一个方法名,而不是像Java一样用init来表示方法名。Objective-C吸收了C和C++的一些令人称道的优点,比如可变参数。如果你在使用方法中总是拿不定总共需要多少个参数,那么你可以使用可变参数,例如NSString的stringWithFormat:方法:+(id)stringWithFormat: (NSString)format, ...;这个方法的第一个参数是NSString类型的参数format,但第二个参数就是一个可变参数。这样的参数不仅没有确切的参数数目,而且也无法得知其具体类型。对于stringWithFormat:方法而言,这些不确定因素只能通过已确定的参数format来确定。因此这个方法需要通过format字符串中的%@、%d等字符串来确定第2个可变参数的数目和类型。如果可变参数的类型和数目与format参数中的格式字符串不相匹配,stringWithFormat:方法将无法正常工作。这样的例子还有Objective-C程序中经常用到的NSLog函数。3.属性属性用于封装对成员变量的访问,是面向对象语言中的一个重要特性,Objective-C也不例外。也许你已经在C++和Java中熟悉了属性的概念,那么我们不再对此进行过多强调。在将实例变量声明为属性的过程中,首先需要声明实例变量,然后使用@property关键字。例如前面的代码中,首先用: NSString name; 声明了实例变量name,然后用@property将name声明为属性: @property(nonatomic,retain)NSString name; 提示:实例变量的声明不是必须的。如果省略实例变量声明的话,编译器会自动提供一个与属性名同名的实例变量。然后在.m文件的implementation语句后使用@synthesize<属性名>;语句。当你这样做完之后,编译器会自动声明变量name的get、set方法,get方法就是变量名,而set方法是单词set加上首字母被大写的变量名,例如: -(NSString) name; -(void)setName:(NSString)newValue; 虽然这些声明在源代码中不可见,但确实是存在的,由编译器在编译时产生。在其中比较复杂的部分是nonatomic和retain关键字的真实含义。在声明属性时,我们可以在@property后面的圆括号中使用多个关键字修饰属性,以指定属性的可访问性、线程管理、内存管理等。由编译器根据这些修饰词产生不同的get、set方法。nonatomic关键字的意思是非原子的,意指对属性进行存取操作时是线程不安全的,如果在多线程环境下,该属性很可能是不同步的,一个线程读取属性值时,另一个属性却修改了属性值,这样两个线程对同一个属性进行操作的情况下,属性的值是不一致的。我们在属性中使用nonatomic的原因是,该属性不会在多线程环境下使用,使用非原子特性能得到较好的性能。而在iOS编程中,性能始终是程序员首先要考虑的问题。retain关键字是我们用得最多的属性修饰符之一,它和属性的内存管理有关。这样在对这个属性进行赋值操作时,在编译器自动生成(如果你使用了@synthesize关键字的话)的Set方法代码中,会对实例变量进行retain操作。对于Objective-C对象类型的实例变量而言,使用retain操作使得属性在赋值后一直到对象被销毁之前始终可用。如果实例变量或属性并不是Objective-C对象类型,而是一个简单类型,如BOOL、int、id、float,则用asign关键字替换retain关键字。这样,属性在赋值时不会被持有,这样导致的直接后果是:刚对一个属性赋值后,再访问这个属性,这个属性就变成空了。关于Objective-C的内存管理,更多内容会在后面介绍。属性还可以用readonly、readwrite进行修饰,分别用于创建只读的属性和可读可写属性。属性声明之后,接下来就是在实现文件(.m文件)中实现属性的get、set方法。这些方法你可以选择自己去实现,也可以让Objective-C替你实现,只需要使用@synthesize或者@dynamic编译器指令。也许你已经习惯书写传统C++和Java的 get、set方法,虽然实际上那是一件相当枯燥的事情。在Objective-C中,你完全不需要这样做,除非你真的需要。在实现的.m文件中,使用@synthesize关键字,可以自动产生属性的get、set方法代码。而这一切不是在源代码中进行的,而是编译器在编译时产生的,因此你不会在源代码中看到自动产生的代码。@dynamic指令则是在运行时才产生这些代码。不管使用@synthesize还是@dynamic,这些自动产生的代码均不可见,但它们是存在的。 3.2.2 消息机制 消息是Objective-C区别于其他语言的最大的地方,它其实是Objective-C特有的方法调用语法。同C++和Java的方法调用一样:1)消息能够接受参数;2)消息可以嵌套调用;3)消息既可以发送Objective-C对象,也可以发送给类。1.消息的参数一个没有参数的消息是这样的: [object methodWithoutParameter]; 如果要调用的方法带有参数,则这个消息是这样的: [object methodWithOneParameter: value]; 注意,当方法没有参数时,其方法名后没有冒号。当方法有多个参数时,其方法名如我们前面所述,会有多个带冒号的参数: [object methodWithFirstParameter:value1 withSecondParameter:value2]; 2.消息的嵌套当要进行一个嵌套的方法调用时,会使用嵌套消息: [textView setTextColor:[UIColor whiteColor]]; 内层的消息[UIColor whiteColor]首先调用并返回一个UIColor,然后将这个临时的UIColor对象作为外层消息的参数传入。即第1个消息的输出作为第2个消息的输入。3.接收者如前面所举的例子中,消息的第一个元素object和textView都是消息的接收者,即我们要将消息发给的对象。除了接收者可以是对象以外,接收者还可以是一个类。因为在方法的种类中,不仅仅有实例方法,还有类方法。使用类作为接收者,就能调用类方法: NSMutableString mstring=[NSMutableString stringWithString:@””]; 3.2.3 Objective-C 的内存管理 内存管理是资源管理的重要部分,在iPhone中尤其如此(因为其内存有限)。相对于Java语言的垃圾回收机制而言,Cocoa的内存管理相当粗糙。这意味着对Objective-C程序员而言,需要做更多的工作,即使是相当有经验的程序员,在这方面也很难不犯错,尤其是不使用ARC的情况下。本书不讲述ARC(即iOS SDK 5.0以后的自动引用计数),因为在iOS企业应用中会大量使用第三方框架,这些框架大部分不使用ARC,这给我们在项目中应用ARC带来许多困难——要么你要单独设置每个.m文件的ARC选项,要么你得放弃使用该框架,这在很多时候给我们带来困惑。因此,本书不推荐使用ARC。1.对象的生命周期每个对象都有生命周期,程序员要知道一个对象的生命周期是什么,就需要仔细回忆一下这个对象是什么时候创建的。每当对象创建出来,它的生命就已经开始了,一直到操作系统释放了该对象,对象的生命才结束。但操作系统怎么知道一个对象应该释放了呢?Objective-C采用了两种内存管理模式:基于计数器的内存管理和基于自动释放池的内存管理。这两种内存管理模式会采用不同的方式来通知操作系统,何时应该释放一个内存对象。此外,Objective-C 2.0以后也支持基于垃圾回收的内存管理,但垃圾回收只限于Mac,而无法在iOS中使用。基于计数器的内存管理和基于自动释放池的内存管理我们在下面介绍。而基于垃圾回收的内存管理则不属于本书讨论的范围。2.基于计数器的内存管理在这种模式下,iOS对内存对象的生命周期管理是通过引用计数来进行的。每个对象都有一个引用计数器,它记录了对象被使用的情况。如果计数器的值为0,表示该对象不再被使用,对象的dealloc方法被调用, dealloc方法是对象的销毁方法,于是对象被销毁。要知道一个对象的计数器值是多少,可以发送retainCount方法: NSLog(@”%d”,[object retainCount]); 当使用alloc、copy、new三种方法之中的任一种方法创建对象时,对象计数器会被自动设置为1。此外,如果向对象发送retain消息,对象计数器会自动加1。而向对象发送release消息,对象计数器会自动减1。因此,在使用计数器情况下的内存管理应当遵循以下原则:alloc、copy或者new总是和release配套使用。如果你通过alloc、copy或者new方法创建了对象,那么必然跟随着一个release。如果这个对象不是使用这3种方法之一创建的,则不需要一个配套的release。retain总是和release配套使用。如果对象创建后发送了1个retain消息,则需要配套1个release消息。release的使用时机。对于临时对象,如果使用过alloc、copy、new以及retain之后,当不再使用该临时对象时,就可以使用release消息。如果该对象不是临时对象,而是类的成员,则在类的dealloc方法中release对象。对于不是使用alloc、copy、new方法创建的对象,如果该对象是一个临时对象,则不要对该对象进行retain操作,也不要对该对象进行release;如果该对象是类的成员,则需要在获取该对象时retain,在dealloc方法中release。3.基于自动释放池的内存管理如前面讲述,使用基于计数器的内存管理十分麻烦,程序员必须对自己创建的每一个对象是否使用了alloc、copy、new、retain方法了如指掌,同时依据一系列规则适时地并在恰当的地方使用release消息。而且有时候要明白一个对象什么时候不再使用并不是一件容易的事情。如果你不想使用对象计数器进行内存管理,则自动释放池是你的另外一个选择。Cocoa引入了自动释放池(autorelease pool)的概念。自动释放池实际是一个对象集合或对象容器的概念。如果你把所有的对象在创建时,都放到这个池中,则自动释放池被销毁时,池中的对象都会接收到release消息。要把对象加入到自动释放池中,只需在创建对象的同时调用autorelease方法。该方法由NSObject提供: -(id) autorelease; 例如下面的代码,当对象string一创建就被放到了自动释放池里: NSString string=[[[NSString alloc]initWithString:@”I am a string”] autorelease]; 那么,这个自动释放池是什么时候创建的?我们并没有创建它,它是Foundation框架自动为我们创建的。当我们使用Xcode新建任何一个iPhone应用程序时,Foundation框架创建的模板代码中总是有这样的代码,你可以在应用程序委托的实现文件中找到它: NSAutoreleasePool pool; pool=[[NSAutoreleasePool alloc]init]; ... [pool release]; 其实我们的HelloWorld程序中也有类似的代码。原来,应用程序一开始就创建了这个自动释放池,并立即成为当前活动的池。我们使用对象的autorelease消息就是把对象放入这个池中。当程序退出时,最后的[pool release]或[pool drain]代码会向池中对象发送release消息。这样,对象会从创建开始,一直存在到应用程序结束。这样无疑会造成一定的内存浪费,整个应用程序运行期间,随着对象的不断创建,内存只见增加不见减少,容易造成内存资源的紧张。很显然,并不适合内存使用率较高的应用程序。本书的建议,程序员主要使用基于计数器的内存管理模式,自动释放池模式的使用则适可而止。提示:[pool release]方法适用于Mac OS的所有版本,而[pool drain]方法只适用于Mac OS 10.4(Tiger)以上版本。 3.2.4 类别和协议 1.类别类别是另一种为现有类添加新行为的方法。不同于子类,类别实际上是Objective-C的一种动态行为,它利用了运行时分配机制。因此,类别甚至不需要拥有原类的源代码。此外,类别不能向现有的类中添加实例变量。要声明一个类别,你需要使用类声明时使用的@interface关键字,如: @interface NSString(NumberConvenience) -(NSNumber)lengthAsNumber; @end 注意,这很像是一个类的声明。首先它使用@interface 类名开始,以@end结束。但实际上,NSString的类名加上其后的圆括号,表明这是一个对现有类NSString的补充或扩充。圆括号说明扩充方式为通过类别扩充而非通过继承来扩充。圆括号中的单词是类别的名称,本例中的类别名称是NumberConvenience。另外,第2行的方法声明语句也很像是NSString的成员方法。但实际上NSString类中根本没有这个方法。这个方法是类别为Cocoa类NSString新增加的。此外,由于类别不能扩充实例变量这一限制,类别的声明中不会出现用于声明实例变量的{}符号。类别主要是定义对现有类的扩充方法,因此类别的实现中(.m文件)就需要对这些新方法一一进行实现: @implementation NSString(NumberConvenience) -(NSNumber)lengthAsNumber{ ... } @end 这个实现文件跟类的实现文件没有多大区别,除了圆括号中的类别名外。接下来,你可以像这样调用这个新方法lengthAsNumber(假设NumberConvenience类别声明是定义在NSStringCategory.h头文件里): #import “NSStringCategory.h” ... NSNumber number=[@”hello” lengthAsNumber]; NSLog(@”length by NSNumber:%d”, [number intValue]); 就好像lengthAsNumber本来就是NSString中已经存在的方法一样。类别有许多好处,比如把类的实现分散在多个implementation文件里(如果使用类,你做不到这点,这就好像C#中的分部类),或者用于创建非正式协议(如下面有关协议的内容所述)。但是,类别仍然有一些限制,在类别的使用中一定要注意以下两点:类别仅仅是一堆方法的集合,你无法为类添加实例变量。类别不能解决命名冲突,如果类别中的方法与类原有的方法重名,则类中的方法被覆盖。2.协议Objective-C的协议等同于Java中接口的概念。下面我们来讨论协议的声明: @protocol NSCopying -(id)copyWithZone: (NSZone)zone; ... @end 协议看起来就像类别的声明,还是一堆方法声明的集合。但@protocol关键字的出现说明了这是一份正式协议。正式协议的意思是,每个采用(Java中用实现implements这个词)这份协议的类必须实现这份协议中的所有方法。这种说法一直持续到Objective-C 2.0。从Objective-C 2.0开始,协议中的方法可以有选择地由类实现。对于需要实现的方法,使用@required关键字修饰,对于可选择性地实现的方法,使用@optional关键字修饰,比如: @protocol TheProtocol @required -(void)firstMethod; -(void)secondMethod; @optional -(void)thirdMethod; @end 这个协议规定,第1、2个方法是必须实现的,而第3个方法可以实现,但不要求一定实现。如果一个类要采用(或实现)这个协议,则需要在@interface中这样声明: @interface MyClass:NSobject<TheProtocol> 而MyClass类的实现中,则应当实现该协议规定的2个必选方法及1个可选的方法。除了正式协议外,我们也可以采用非正式协议。非正式协议不需要采用@protocol关键字声明,但需要创建一个类别,例如MyCategory: @interface NSObject(MyCategory) -(void)doSomething; ... @end 由于NSObject是所有Cocoa类的根类,这个类别实际上指明了任何类都可以实现这些方法。从而可以向任何对象发送这些消息,而不需要在类的声明中做任何特别的说明。 3.2.5 反射机制 同其他高级语言一样,Objective-C也提供了运行时支持——即Java所谓的反射机制,这充分体现了Objective-C的动态性特征。尤其在Mac OS X 10.5以后,苹果对Objective-C运行时API进行了重要的升级,以提供对64位模式的支持。Objective-C运行时API包含了众多函数和结构体的定义,然而,我们不准备在此介绍庞大的Objective-C 运行时库。如果要全面了解这些API,请翻阅苹果运行时库参考。通常,我们不需要直接调用Objective-C运行时API,Cocoa框架已经把它的许多有用函数进行了封装,从而使我们更容易调用。1.获取类信息首先,我们知道NSArray等集合对象中不限制所存储的对象类型,只要它是一个NSObject就行。但有时候,我们想知道我们刚刚放进去的一个对象到底是什么类型(程序员总是那么健忘),是一个字符串?还是别的什么?我们可以发送class消息: id class=[[array objectAtIndex:0]class]; id类型(即对象)其实是一个objc_object结构: typedef struct objc_object { Class isa; } id; NSObject的class方法实际是上返回了这个结构中的isa成员。isa指向了一个Class对象,因此除了发送class消息外,我们也可以使用isa成员来访问Class对象。Class对象指向了该对象所属的类(即“类对象”,Objective-C把类也看成是对象,以贯彻“万物皆对象”的原则)。Class对象实际上是一个objc_class结构: typedef struct objc_class Class; struct objc_class { Class isa; Class super_class; / followed by runtime specific details... / }; 注意:这个结构很象是objc_object,但多了一个指向父类的super_class成员。也就是说,对象跟类的区别仅在于,对象中不保存继承关系,而类(或“类对象”)保存了继承关系。因此我们是通过类而不是对象来追溯类的“父类”、“祖父类”等。我们有时需要比较一个对象是否属于某个类,可以使用类似的代码: if (obj->isa ==[NSString class]){ ... } 而super_class成员指向了父类对象,通过它我们可以访问父类的信息。在Cocoa中还有一个“元类”的概念,即“类对象的类”。因此完整的类信息称为“类对”,即由“类对象”和“元类”构成。如果向一个对象发送class方法,我们可以得到“类对象”,而如果再向“类对象”发送class消息,则返回的就是“元类”(meta class)。每个类只能有一个元类,其包含了类方法列表。而类对象不同,它包含了对象的方法列表。2.选择器选择器实际上是一个方法名称,用@selector关键字来指定一个选择器,选择器用于查询对象的某个方法,例如: @selector(setResponse:) 通过NSObject的responseToSelector方法,我们可以动态地查询某个对象是否存在指定的方法。该方法需要指定一个选择器参数: if([object responseToSelector:@selector(setResponse:)]){ ... } 如果object对象能够响应setResponse:方法,则返回YES,否则返回NO。如果确定某对象能响应指定方法,则可以通过performSelector:方法进行调用: [anObject performSelector:@selector(method)]; 如果该方法带有参数,则使用performSelector: withObject:方法传递参数: [anObject performSelector:@selecor(method) withObject:obj]; 如果有2个参数,则使用performSelector: withObject: withObject:。更多的参数或者有返回值,则使用NSInvocation。除了向对象发送 performSelector 消息之外,Objective-C还提供了objc_msgSend 函数,你可以用它向任何对象发送一条消息:objc_msgSend( anObject,@selector(method),obj);要使用objc_msgSend 函数,需要导入头文件,其完整定义如下: id objc_msgSend(id theReceiver, SEL theSelector, ...) 函数的第1个参数指向消息的接收者(即该方法的对象),第2个参数是一个选择器(即方法),第3个参数是一个可变参数,是该方法的1个或多个参数,如果该方法没有参数,用一个nil代替。方法的返回值通过函数的返回值返回。3.类的动态创建要在代码中创建类,而不是通过静态的.h和.m文件定义类,可以使用Object C运行时库API(需要#include ): Class newClz=objc_allocateClassPair([NSError class], "RuntimeErrorSubclass", 0); class_addMethod(newClz, @selector(report), (IMP)ReportFunction, "v@:"); objc_registerClassPair(newClz); 首先,使用objc_allocateClassPair动态函数创建了一个类,并在参数中指明该类的父类和类名。用class_addMethod函数为该类增加了一个方法report,这个方法是由函数ReportFunction实现的,由于该函数至少应包含两个参数self和_cmd,因此定义了该方法有3个参数,类型分别为v、@、:(一个返回值,self,_cmd)。v代表void,指定了方法的返回值;@代表了id类型(对象),指定了方法的固定参数self;: 表示选择器类型(SEL),指定了固定参数_cmd。因此函数ReportFunction应当实现为: void ReportFunction(id self, SEL _cmd) { // 实现代码 } 最后,新类被注册为类对(Class Pair)。类对注册后,即可在代码中这样使用类newClz: id obj =[[newClz alloc] init]; [obj performSelector:@selector(report)]; [obj release]; 4.类的动态加载Cocoa的Foundation框架提供的NSClassFromString函数类似于Java的Class.forName()方法: Class clz=NSClassFromString(@"MyClass"); 返回对象为“类对象”Class。通过这种方法,我们从字符串构建类实例就不再是什么问题: id obj=[[clz alloc]init] 或者 id obj=[[NSClassFromString(@”MyClass”) alloc]init]; 这使得我们可以在运行时而不是编译时加载类,同时,不需要#import “MyClass”。5.方法的动态调用通过@selector关键字我们已经可以在一定程度上实现方法的动态调用。然而更动态的方式是通过Fundation框架的NSSelectorFromString函数,它可以直接从字符串获得一个选择器: SEL sel = NSSelectorFromString(@"doSomethingMethod:") if([object respondsToSelector:sel]){ [object performSelector:sel withObject:color]; } 3.2.6 谓词 Cocoa提供NSPredicate类,用于描述条件和计算对象是否匹配指定条件。类似于SQL语句,通过NSPredicate,可以将条件的计算从代码中分离出来,从而在比较对象时避免使用硬编码。1.创建谓词首先需要创建一个NSPredicate对象: NSPredicate predicate=[NSPredicate redicateWithFormat:@”name==’Herbie’”]; 类方法predicateWithFormat常用于创建一个NSPredicate对象。仅需要提供一个代表计算条件的字符串。字符串@"name=='Herbie'"代表了需要进行计算的C条件表达式。事实上,除了==运算符外,谓词的条件表达式支持括号和C语言的比较运算符和逻辑运算符。下面我们来看看谓词是如何进行计算的。2.谓词的计算要对谓词进行计算,需要将谓词应用在某个对象身上。例如: BOOL match=[predicate evaluateWithObject: car]; 谓词predicate的evaluateWithObject方法实际上对car对象进行了计算,并返回BOOL值YES或NO。前面的条件表达式@"name=='Herbie'",表明将用car的name属性与字符串Herbie进行比较,如果相等,则返回YES,否则返回NO。谓词可以用任何对象作为参数进行计算,包括数组或集合。如果persons是一个包含了多个person实例的NSArray数组,那么我们可以用谓词计算或过滤出其中gender(性别)属性为男性的对象: NSPredicate predicate=[NSPredicate predicateWithFormat: @”gender==’M’”]; NSArray result=[persons filteredArrayUsingPredicate: predicate]; 谓词将对persons中的所有对象进行条件计算,把gender等于M的对象加到结果集数组中返回。3.在条件中使用变量有时候,在构建谓词时,使用变量组成条件表达式将更方便。这就类似于JDBC中的预编译语句,Where条件子句中的表达式可以使用可变参数。只需在SQL语句中使用问号?来代表可变参数即可。这样的好处是显而易见的,我们就可以重用预编译语句,节省数据库编译上SQL语句的时间。我们只需在执行预编译语句时,提供不同的可变参数值,即可执行不同的SQL查询。同样,我们也可以在条件表达式中使用格式化字符串或占位符,来作为条件表达式中的可变部分。例如: NSPredicate predicate=[NSPredicate predicateWithFormat:@”name==%@”,@”Herbie”]; 这和原来没有任何区别。占位符%@表示这里将被一个对象(id类型)所替换。如果想在表达式左边使用变量,可以使用%K作为占位符,例如: predicate=[NSPredicate predicateWithFormat:@”%K==%@”,@”name”,@”Herbie”]; 这与前面一条语句是等效的。提示:%K中的字母K代表的是keypath(键路径)。在后面介绍。除此之外,我们还可以使用NSLog中使用的各种占位符,如%d等。当然,不使用占位符,还可以使用命名的键-值对(NSDictionary)作为条件变量。例如: predicate=[NSPredicate predicateWithFormat:@”name==$NAME”]; 这里$NAME就代表了一个变量(而不是对象),这个变量值未指定。如果要指定这个变量的值,需要在NSDictionary中加入一个Key为Name的对象,同时用这个NSDictionary(Cocoa将这个NSDictionary称为环境变量SubstitutionVariances)创建新的predicate: NSPredicate*predicate=[NSPredicatepredicateWithFormat: @"name=$NAME"]; predicate=[predicatepredicateWithSubstitutionVariances:dic]; 然后使用新的predicate去进行计算。也就是说,通过这种方式,我们提交一个NSDictionary作为谓词变量。4.BETWEEN和INBETWEEN运算符用于表示位于某个区间中的取值。例如: predicate=[NSPredicate predicateWithFormat:@”age BETWEEN{16,50}”]; 该条件表达式表示age属性值在16到50之间的对象。IN用于测试某个值处于一个集合范围内的情况。例如: predicate=[NSPredicate predicateWithFormat: @”name IN {‘Herbie’,’Elvis’,’Phoenix’}”]; 该条件表达式表示name属性等于这三者之一的对象。5.字符串匹配谓词常用于判断字符串的匹配,除使用比较运算符外,谓词表达式还支持多种对字符串进行计算的运算符:BEGINSWITH用于判断一个字符串的开头是否包含另一个字符串。ENDSWITH用于判断一个字符串的结尾是否包含另一个字符串。CONTAINS用于判断一个字符串中是否包含另一个字符串。LIKE运算符用于进行字符串的匹配。如同SQL语法一样,谓词表达式中的LIKE运算符支持两种通配符:和?,号匹配任意个数的任意字符,?号匹配1个任意字符。此外,[c]选项用于表示忽略大小写,[d]选项用于表示忽略发音符号,[cd]选项用于表示同时忽略大小写和发音符号。例如: predicate=[NSPredicate predicateWithFormat: @”name BEGINSWITH[cd] ‘HER’”]; 提示:如果你想在谓词表达式中使用正则式,则需要使用MATCHES运算符。6.KeyPath和SELFCocoa中经常引用KeyPath的概念。键路径KeyPath实际上和文件系统中路径概念无关,KeyPath是面向对象语言如Java中“.”语法的概念,比如: indexPath.row 这就是一个KeyPath。用前面的例子,我们想匹配persons数组中名称长度超过10的对象,那么在谓词表达式中不能使用name作为主语了(假设我们把谓词表达式分为“主语+运算符+宾语”结构,位于运算符左边的操作数是主语,而位于运算符右边的操作数就是宾语)。因为name(具体地说,指数组中某个对象的name属性)只是一个字符串,它的长度应该用name.length表示。如前面所说,name.length就是一个KeyPath,用它作为表达式的主语是恰当的。那么,这个谓词应该这样构建: predicate=[NSPredicate predicateWithFormat:@”name.length > 10”]; 然后再对persons数组中的每个对象进行计算: NSArray result=[persons filteredArrayUsingPredicate: predicate]; 其实KeyPath“name.length”还可以是“SELF.name.length”,这二者是完全等效的。SELF用来表示应用了谓词的对象。SELF经常可以省略,但在一种情况下不能被省略。让我们来假设这样的情况: predicate=[NSPredicate predicateWithFormat:@”SELF ==@’Herbie’]; BOOL match=[predicate evaluateWithObject:@”Rubby”]; 先看第2句,我们把谓词应用到一个字符串对象@"Rubby"。那么第1句中的SELF就不能省略了。该谓词的KeyPath使用SELF,表示我们要用它(而不是它的属性)直接和另一个字符串@"Herbie"进行比较,这是可以理解的。在这种情况下,你不能省略SELF,否则谓词表达式就不完整了,因为它缺乏了“主语”这个关键的语法元素。

优秀的个人博客,低调大师

《企业级ios应用开发实战》一2.3 Cocoa Touch 框架简介

2.3 Cocoa Touch 框架简介 Cocoa Touch框架是进行iPhone应用程序开发工作的主要框架,主要包括UIKit和Foundation(NS)框架,这些库统称为Cocoa Touch框架。该框架完全是面向对象的,它是Cocoa框架的子集。注意:Cocoa框架早先是用于Mac OS X上的一个面向对象的应用程序快速开发(Rapid Application Development,RAD)框架,包含了Foundation和App Kit框架,可用于开发Mac OS X系统的应用程序。而随后苹果又在Cocoa中加入了对iOS的支持,即UI Kit框架。习惯上,把UI Kit框架、Foundation框架及一些附属框架合称为Cocoa Touch框架,如图2-2所示。 注意,App Kit用于Mac OS X。而UIKit用于iOS(它参考了App Kit的实现)。Foundation框架和附属框架则是二者所共有。Cocoa Touch是iOS上关于用户交互的可编程框架。采用源自Cocoa和强大的Mac桌面的技术,Cocoa Touch和iOS针对多点触控进行了重新设计。由于其小巧的外形,iPhone上的按钮、表格表单、页面过渡以及触摸手势都是独特的,而这些界面功能,都可以通过Cocoa Touch 框架实现。Cocoa 框架采用“模型-视图-控制器”(MVC)设计模式。“模型”封装应用程序的数据,“视图”显示和编辑数据,“控制器”处理前两者之间的逻辑关系。这种分工负责的方式使得程序易于设计,实现和维护,如图2-3所示。

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册