
iOS sdk中的view是UIView,我们可以很方便的自定义一个View。 创建一个 Window-based Application程序,在其中添加一个Hypnosister的类,这个类选择继承UIObject。修改这个类,使他继承:UIView @interface HypnosisView : UIView 自定义View的关键是定义drawRect: 方法,因为主要是通过重载这个方法,来改变view的外观。例如,可以使用下面代码绘制一个很多环中环的效果的view。 View Code 这样view的效果如下图: 我们可以继续绘制一些东西,比如绘制文字,将下面代码添加带这个方法后面。 // Create a string NSString *text =@"我是朱祁林,不是朱麒麟";// Get a font to draw it in UIFont *font = [UIFont boldSystemFontOfSize:28];// Where am I going to draw it? CGRect textRect; textRect.size = [text sizeWithFont:font]; textRect.origin.x = center.x - textRect.size.width /2.0; textRect.origin.y = center.y - textRect.size.height /2.0;// Set the fill color of the current context to black [[UIColor blackColor] setFill];// Set the shadow to be offset 4 points right, 3 points down, // dark gray and with a blur radius of 2 points CGSize offset = CGSizeMake(4, 3); CGColorRef color = [[UIColor darkGrayColor] CGColor]; CGContextSetShadowWithColor(context, offset, 2.0, color);// Draw the string [text drawInRect:textRect withFont:font]; 效果: 如果view过大,我们可以把它放置到一个UIScrollView中间,这样就可以进行拖动了。UIScrollView与View的关系如下图: 使用下面代码创建一个比iPhone屏幕大4倍的View,然后通过UIScrollView来展示,代码如下: - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {//创建一个窗体大小的CGRect CGRect wholeWindow = [[self window] bounds];// 创建一个窗体大小的HypnosisView实例 view = [[HypnosisView alloc] initWithFrame:wholeWindow]; UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:wholeWindow]; [[self window] addSubview:scrollView];// Make your view twice as large as the window CGRect reallyBigRect; reallyBigRect.origin = CGPointZero; reallyBigRect.size.width = wholeWindow.size.width *2.0; reallyBigRect.size.height = wholeWindow.size.height *2.0; [scrollView setContentSize:reallyBigRect.size]; CGPoint offset; offset.x = wholeWindow.size.width *0.5; offset.y = wholeWindow.size.height *0.5; [scrollView setContentOffset:offset];// Create the view view = [[HypnosisView alloc] initWithFrame:reallyBigRect]; [view setBackgroundColor:[UIColor clearColor]]; [scrollView addSubview:view]; [scrollView release]; [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade]; [[self window] makeKeyAndVisible];return YES; } 这样我们就可以拖动来展示看不到的view了,如下图: 通过UIScrollView我们还可以设置view的缩放功能,将下面代码添加到中。这样我们就可以使用两根手指缩放view了。 // Enable zooming [scrollView setMinimumZoomScale:0.5]; [scrollView setMaximumZoomScale:5]; [scrollView setDelegate:self]; 总结:文本简单的总结了一下自定义view的使用。 代码:Hypnosister.zip 本文转自麒麟博客园博客,原文链接:http://www.cnblogs.com/zhuqil/archive/2011/07/27/2118843.html,如需转载请自行联系原作者
UIWebView是iOS sdk中一个最常用的控件。是内置的浏览器控件,我们可以用它来浏览网页、打开文档等等。这篇文章我将使用这个控件,做一个简易的浏览器。如下图: 我们创建一个Window-based Application程序命名为:UIWebViewDemo UIWebView的loadRequest可以用来加载一个url地址,它需要一个NSURLRequest参数。我们定义一个方法用来加载url。在UIWebViewDemoViewController中定义下面方法: - (void)loadWebPageWithString:(NSString*)urlString { NSURL *url =[NSURL URLWithString:urlString]; NSLog(urlString); NSURLRequest *request =[NSURLRequest requestWithURL:url]; [webView loadRequest:request]; } 在界面上放置3个控件,一个textfield、一个button、一个uiwebview,布局如下: 在代码中定义相关的控件:webView用于展示网页、textField用于地址栏、activityIndicatorView用于加载的动画、buttonPress用于按钮的点击事件。 @interface UIWebViewDemoViewController :UIViewController<UIWebViewDelegate> { IBOutlet UIWebView *webView; IBOutlet UITextField *textField; UIActivityIndicatorView *activityIndicatorView; } - (IBAction)buttonPress:(id) sender; - (void)loadWebPageWithString:(NSString*)urlString; @end 使用IB关联他们。 设置UIWebView,初始化UIActivityIndicatorView: - (void)viewDidLoad { [super viewDidLoad]; webView.scalesPageToFit =YES; webView.delegate=self; activityIndicatorView = [[UIActivityIndicatorView alloc] initWithFrame : CGRectMake(0.0f, 0.0f, 32.0f, 32.0f)] ; [activityIndicatorView setCenter: self.view.center] ; [activityIndicatorView setActivityIndicatorViewStyle: UIActivityIndicatorViewStyleWhite] ; [self.view addSubview : activityIndicatorView] ; [self buttonPress:nil];// Do any additional setup after loading the view from its nib.} UIWebView主要有下面几个委托方法: 1、- (void)webViewDidStartLoad:(UIWebView *)webView;开始加载的时候执行该方法。 2、- (void)webViewDidFinishLoad:(UIWebView *)webView;加载完成的时候执行该方法。 3、- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error;加载出错的时候执行该方法。 我们可以将activityIndicatorView放置到前面两个委托方法中。 - (void)webViewDidStartLoad:(UIWebView *)webView { [activityIndicatorView startAnimating] ; }- (void)webViewDidFinishLoad:(UIWebView *)webView { [activityIndicatorView stopAnimating]; } buttonPress方法很简单,调用我们开始定义好的loadWebPageWithString方法就行了: - (IBAction)buttonPress:(id) sender { [textField resignFirstResponder]; [self loadWebPageWithString:textField.text]; } 当请求页面出现错误的时候,我们给予提示: - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { UIAlertView *alterview = [[UIAlertView alloc] initWithTitle:@"" message:[error localizedDescription] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil]; [alterview show]; [alterview release]; } 总结:本文通过实现一个简单的浏览器,说明了uiwebview的方法和属性,相信通过这个例子,应该明白uiwebview的使用了。 代码:UIWebViewDemo.zip 本文转自麒麟博客园博客,原文链接:http://www.cnblogs.com/zhuqil/archive/2011/07/28/2119923.html,如需转载请自行联系原作者
1.概述 Jenkins是基于Java开发的一种持续集成工具,用于监控持续重复的工作,功能包括: 持续的软件版本发布/测试项目 监控外部调用执行的工作 2.搭建 2.1环境准备 首先我们要准备搭建的环境,配置如下: 操作系统:CentOS 6.x JDK版本:JDK1.7 2.2安装Jenkins 执行如下命令: sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo sudo rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key sudo yum install jenkins rpm -ql jenkins 2.3配置Jenkins vi /etc/sysconfig/jenkins 然后编辑PORT即可(默认8080,也可以直接使用默认): # Port Jenkins is listening on. # Set to -1 to disable # JENKINS_PORT="12980" 这里我们讲PORT设置为12980 2.4启动/停止/重启 # 启动 service jenkins start # 停止 service jenkins stop # 重启 service jenkins restart 3.使用 我们输入Jenkins的状态使用命令查看运行状态,命令如下: service jenkins status 现实对应的PID进程号: jenkins (pid 1903) is running... 然后,我们在浏览器访问:http://jenkins.company.com:12980,如果能正常进入,说明搭建成功,若进入不了,说明搭建失败,具体原因,我们可以查看jenkins的启动日志,输入如下命令: cat /var/log/jenkins/jenkins.log 查看异常信息,根据日志信息定位问题,查看解决方案。 当我们正常进入,会出现如下界面,如图所示: 接下来我们安装一些必要的插件:SCM Sync Configuration Plugin ,GitHub plugin ,GIT plugin ,GIT client plugin ,安装结束后重启jenkins。若插件在线无法安装,可离线下载,地址:https://updates.jenkins-ci.org/download/plugins/ 联系方式: 邮箱:smartloli.org@gmail.com Twitter:https://twitter.com/smartloli QQ群(Hadoop - 交流社区1):424769183 温馨提示:请大家加群的时候写上加群理由(姓名+公司/学校),方便管理员审核,谢谢! 热爱生活,享受编程,与君共勉! 本文转自哥不是小萝莉博客园博客,原文链接:http://www.cnblogs.com/smartloli/,如需转载请自行联系原作者
1.概述 最近有同学反应,如何在配置了HA的Hadoop平台运行MapReduce程序呢?对于刚步入Hadoop行业的同学,这个疑问却是会存在,其实仔细想想,如果你之前的语言功底不错的,应该会想到自动重连,自动重连也可以帮我我们解决运行MapReduce程序的问题。然后,今天我赘述的是利用Hadoop的Java API 来实现。 2.介绍 下面直接附上代码,代码中我都有注释。 2.1Java操作HDFS HA的API 代码如下: /** * */ package cn.hdfs.mr.example; import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; /** * @author dengjie * @date 2015年3月24日 * @description TODO */ public class DFS { public static void main(String[] args) { Configuration conf = new Configuration(); conf.set("fs.defaultFS", "hdfs://cluster1");//指定hdfs的nameservice为cluster1,是NameNode的URI conf.set("dfs.nameservices", "cluster1");//指定hdfs的nameservice为cluster1 conf.set("dfs.ha.namenodes.cluster1", "nna,nns");//cluster1下面有两个NameNode,分别是nna,nns conf.set("dfs.namenode.rpc-address.cluster1.nna", "10.211.55.26:9000");//nna的RPC通信地址 conf.set("dfs.namenode.rpc-address.cluster1.nns", "10.211.55.27:9000");//nns的RPC通信地址 conf.set("dfs.client.failover.proxy.provider.cluster1", "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider");//配置失败自动切换实现方式 FileSystem fs = null; try { fs = FileSystem.get(conf);//获取文件对象 FileStatus[] list = fs.listStatus(new Path("/"));//文件状态集合 for (FileStatus file : list) { System.out.println(file.getPath().getName());//打印目录名 } } catch (IOException e) { e.printStackTrace(); } finally { try { if (fs != null) { fs.close(); } } catch (IOException e) { e.printStackTrace(); } } } } 接下来,附上 Java 运行 MapReduce 程序的 API 代码。 2.2Java 运行 MapReduce 程序的 API 以 WordCount 为例子,代码如下: package cn.jpush.hdfs.mr.example; import java.io.IOException; import java.util.Random; import java.util.StringTokenizer; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import cn.jpush.hdfs.utils.ConfigUtils; /** * * @author dengjie * @date 2014年11月29日 * @description Wordcount的例子是一个比较经典的mapreduce例子,可以叫做Hadoop版的hello world。 * 它将文件中的单词分割取出,然后shuffle,sort(map过程),接着进入到汇总统计 * (reduce过程),最后写道hdfs中。基本流程就是这样。 */ public class WordCount { private static Logger log = LoggerFactory.getLogger(WordCount.class); public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> { private final static IntWritable one = new IntWritable(1); private Text word = new Text(); /* * 源文件:a b b * * map之后: * * a 1 * * b 1 * * b 1 */ public void map(Object key, Text value, Context context) throws IOException, InterruptedException { StringTokenizer itr = new StringTokenizer(value.toString());// 整行读取 while (itr.hasMoreTokens()) { word.set(itr.nextToken());// 按空格分割单词 context.write(word, one);// 每次统计出来的单词+1 } } } /* * reduce之前: * * a 1 * * b 1 * * b 1 * * reduce之后: * * a 1 * * b 2 */ public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> { private IntWritable result = new IntWritable(); public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int sum = 0; for (IntWritable val : values) { sum += val.get(); } result.set(sum); context.write(key, result); } } @SuppressWarnings("deprecation") public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); conf.set("fs.defaultFS", "hdfs://cluster1"); conf.set("dfs.nameservices", "cluster1"); conf.set("dfs.ha.namenodes.cluster1", "nna,nns"); conf.set("dfs.namenode.rpc-address.cluster1.nna", "10.211.55.26:9000"); conf.set("dfs.namenode.rpc-address.cluster1.nns", "10.211.55.27:9000"); conf.set("dfs.client.failover.proxy.provider.cluster1", "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"); long random1 = new Random().nextLong();// 重定下输出目录 log.info("random1 -> " + random1); Job job1 = new Job(conf, "word count"); job1.setJarByClass(WordCount.class); job1.setMapperClass(TokenizerMapper.class);// 指定Map计算的类 job1.setCombinerClass(IntSumReducer.class);// 合并的类 job1.setReducerClass(IntSumReducer.class);// Reduce的类 job1.setOutputKeyClass(Text.class);// 输出Key类型 job1.setOutputValueClass(IntWritable.class);// 输出值类型 FileInputFormat.addInputPath(job1, new Path("/home/hdfs/test/hello.txt"));// 指定输入路径 FileOutputFormat.setOutputPath(job1, new Path(String.format(ConfigUtils.HDFS.WORDCOUNT_OUT, random1)));// 指定输出路径 System.exit(job1.waitForCompletion(true) ? 0 : 1);// 执行完MR任务后退出应用 } } 3.运行结果 下面附上部分运行 Log 日志,如下所示: [Job.main] - Running job: job_local551164419_0001 2015-03-24 11:52:09 INFO [LocalJobRunner.Thread-12] - OutputCommitter set in config null 2015-03-24 11:52:09 INFO [LocalJobRunner.Thread-12] - OutputCommitter is org.apache.hadoop.mapreduce.lib.output.FileOutputCommitter 2015-03-24 11:52:10 INFO [LocalJobRunner.Thread-12] - Waiting for map tasks 2015-03-24 11:52:10 INFO [LocalJobRunner.LocalJobRunner Map Task Executor #0] - Starting task: attempt_local551164419_0001_m_000000_0 2015-03-24 11:52:10 INFO [ProcfsBasedProcessTree.LocalJobRunner Map Task Executor #0] - ProcfsBasedProcessTree currently is supported only on Linux. 2015-03-24 11:52:10 INFO [Task.LocalJobRunner Map Task Executor #0] - Using ResourceCalculatorProcessTree : null 2015-03-24 11:52:10 INFO [MapTask.LocalJobRunner Map Task Executor #0] - Processing split: hdfs://cluster1/home/hdfs/test/hello.txt:0+24 2015-03-24 11:52:10 INFO [MapTask.LocalJobRunner Map Task Executor #0] - Map output collector class = org.apache.hadoop.mapred.MapTask$MapOutputBuffer 2015-03-24 11:52:10 INFO [MapTask.LocalJobRunner Map Task Executor #0] - (EQUATOR) 0 kvi 26214396(104857584) 2015-03-24 11:52:10 INFO [MapTask.LocalJobRunner Map Task Executor #0] - mapreduce.task.io.sort.mb: 100 2015-03-24 11:52:10 INFO [MapTask.LocalJobRunner Map Task Executor #0] - soft limit at 83886080 2015-03-24 11:52:10 INFO [MapTask.LocalJobRunner Map Task Executor #0] - bufstart = 0; bufvoid = 104857600 2015-03-24 11:52:10 INFO [MapTask.LocalJobRunner Map Task Executor #0] - kvstart = 26214396; length = 6553600 2015-03-24 11:52:10 INFO [LocalJobRunner.LocalJobRunner Map Task Executor #0] - 2015-03-24 11:52:10 INFO [MapTask.LocalJobRunner Map Task Executor #0] - Starting flush of map output 2015-03-24 11:52:10 INFO [MapTask.LocalJobRunner Map Task Executor #0] - Spilling map output 2015-03-24 11:52:10 INFO [MapTask.LocalJobRunner Map Task Executor #0] - bufstart = 0; bufend = 72; bufvoid = 104857600 2015-03-24 11:52:10 INFO [MapTask.LocalJobRunner Map Task Executor #0] - kvstart = 26214396(104857584); kvend = 26214352(104857408); length = 45/6553600 2015-03-24 11:52:10 INFO [MapTask.LocalJobRunner Map Task Executor #0] - Finished spill 0 2015-03-24 11:52:10 INFO [Task.LocalJobRunner Map Task Executor #0] - Task:attempt_local551164419_0001_m_000000_0 is done. And is in the process of committing 2015-03-24 11:52:10 INFO [LocalJobRunner.LocalJobRunner Map Task Executor #0] - map 2015-03-24 11:52:10 INFO [Task.LocalJobRunner Map Task Executor #0] - Task 'attempt_local551164419_0001_m_000000_0' done. 2015-03-24 11:52:10 INFO [LocalJobRunner.LocalJobRunner Map Task Executor #0] - Finishing task: attempt_local551164419_0001_m_000000_0 2015-03-24 11:52:10 INFO [LocalJobRunner.Thread-12] - map task executor complete. 2015-03-24 11:52:10 INFO [LocalJobRunner.Thread-12] - Waiting for reduce tasks 2015-03-24 11:52:10 INFO [LocalJobRunner.pool-6-thread-1] - Starting task: attempt_local551164419_0001_r_000000_0 2015-03-24 11:52:10 INFO [ProcfsBasedProcessTree.pool-6-thread-1] - ProcfsBasedProcessTree currently is supported only on Linux. 2015-03-24 11:52:10 INFO [Task.pool-6-thread-1] - Using ResourceCalculatorProcessTree : null 2015-03-24 11:52:10 INFO [ReduceTask.pool-6-thread-1] - Using ShuffleConsumerPlugin: org.apache.hadoop.mapreduce.task.reduce.Shuffle@1197414 2015-03-24 11:52:10 INFO [MergeManagerImpl.pool-6-thread-1] - MergerManager: memoryLimit=1503238528, maxSingleShuffleLimit=375809632, mergeThreshold=992137472, ioSortFactor=10, memToMemMergeOutputsThreshold=10 2015-03-24 11:52:10 INFO [EventFetcher.EventFetcher for fetching Map Completion Events] - attempt_local551164419_0001_r_000000_0 Thread started: EventFetcher for fetching Map Completion Events 2015-03-24 11:52:10 INFO [LocalFetcher.localfetcher#1] - localfetcher#1 about to shuffle output of map attempt_local551164419_0001_m_000000_0 decomp: 50 len: 54 to MEMORY 2015-03-24 11:52:10 INFO [InMemoryMapOutput.localfetcher#1] - Read 50 bytes from map-output for attempt_local551164419_0001_m_000000_0 2015-03-24 11:52:10 INFO [MergeManagerImpl.localfetcher#1] - closeInMemoryFile -> map-output of size: 50, inMemoryMapOutputs.size() -> 1, commitMemory -> 0, usedMemory ->50 2015-03-24 11:52:10 INFO [EventFetcher.EventFetcher for fetching Map Completion Events] - EventFetcher is interrupted.. Returning 2015-03-24 11:52:10 INFO [LocalJobRunner.pool-6-thread-1] - 1 / 1 copied. 2015-03-24 11:52:10 INFO [MergeManagerImpl.pool-6-thread-1] - finalMerge called with 1 in-memory map-outputs and 0 on-disk map-outputs 2015-03-24 11:52:10 INFO [Merger.pool-6-thread-1] - Merging 1 sorted segments 2015-03-24 11:52:10 INFO [Merger.pool-6-thread-1] - Down to the last merge-pass, with 1 segments left of total size: 46 bytes 2015-03-24 11:52:10 INFO [MergeManagerImpl.pool-6-thread-1] - Merged 1 segments, 50 bytes to disk to satisfy reduce memory limit 2015-03-24 11:52:10 INFO [MergeManagerImpl.pool-6-thread-1] - Merging 1 files, 54 bytes from disk 2015-03-24 11:52:10 INFO [MergeManagerImpl.pool-6-thread-1] - Merging 0 segments, 0 bytes from memory into reduce 2015-03-24 11:52:10 INFO [Merger.pool-6-thread-1] - Merging 1 sorted segments 2015-03-24 11:52:10 INFO [Merger.pool-6-thread-1] - Down to the last merge-pass, with 1 segments left of total size: 46 bytes 2015-03-24 11:52:10 INFO [LocalJobRunner.pool-6-thread-1] - 1 / 1 copied. 2015-03-24 11:52:10 INFO [deprecation.pool-6-thread-1] - mapred.skip.on is deprecated. Instead, use mapreduce.job.skiprecords 2015-03-24 11:52:10 INFO [Task.pool-6-thread-1] - Task:attempt_local551164419_0001_r_000000_0 is done. And is in the process of committing 2015-03-24 11:52:10 INFO [LocalJobRunner.pool-6-thread-1] - 1 / 1 copied. 2015-03-24 11:52:10 INFO [Task.pool-6-thread-1] - Task attempt_local551164419_0001_r_000000_0 is allowed to commit now 2015-03-24 11:52:10 INFO [FileOutputCommitter.pool-6-thread-1] - Saved output of task 'attempt_local551164419_0001_r_000000_0' to hdfs://cluster1/output/result/-3636988299559297154/_temporary/0/task_local551164419_0001_r_000000 2015-03-24 11:52:10 INFO [LocalJobRunner.pool-6-thread-1] - reduce > reduce 2015-03-24 11:52:10 INFO [Task.pool-6-thread-1] - Task 'attempt_local551164419_0001_r_000000_0' done. 2015-03-24 11:52:10 INFO [LocalJobRunner.pool-6-thread-1] - Finishing task: attempt_local551164419_0001_r_000000_0 2015-03-24 11:52:10 INFO [LocalJobRunner.Thread-12] - reduce task executor complete. 2015-03-24 11:52:10 INFO [Job.main] - Job job_local551164419_0001 running in uber mode : false 2015-03-24 11:52:10 INFO [Job.main] - map 100% reduce 100% 2015-03-24 11:52:10 INFO [Job.main] - Job job_local551164419_0001 completed successfully 2015-03-24 11:52:10 INFO [Job.main] - Counters: 35 File System Counters FILE: Number of bytes read=462 FILE: Number of bytes written=466172 FILE: Number of read operations=0 FILE: Number of large read operations=0 FILE: Number of write operations=0 HDFS: Number of bytes read=48 HDFS: Number of bytes written=24 HDFS: Number of read operations=13 HDFS: Number of large read operations=0 HDFS: Number of write operations=4 Map-Reduce Framework Map input records=2 Map output records=12 Map output bytes=72 Map output materialized bytes=54 Input split bytes=105 Combine input records=12 Combine output records=6 Reduce input groups=6 Reduce shuffle bytes=54 Reduce input records=6 Reduce output records=6 Spilled Records=12 Shuffled Maps =1 Failed Shuffles=0 Merged Map outputs=1 GC time elapsed (ms)=13 Total committed heap usage (bytes)=514850816 Shuffle Errors BAD_ID=0 CONNECTION=0 IO_ERROR=0 WRONG_LENGTH=0 WRONG_MAP=0 WRONG_REDUCE=0 File Input Format Counters Bytes Read=24 File Output Format Counters Bytes Written=24 原文件如下所示: a a c v d d a d d s s x Reduce 结果图,如下所示: 4.总结 我们可以按以下步骤进行验证代码的可用性: 保证 NNA( active 状态)和 NNS( standby 状态)。注意,DN 节点都是正常运行的。 然后,我们运行 WordCount 程序,看能否统计出结果。 若安上述步骤下来,可以统计;我们接着往下执行。若不行,请排查错误,然后继续。 然后,我们 kill 掉 NNA 节点的 NameNode 进程,此时,NNS 的状态会由 standby 转变为 active 接着我们在支持 WordCount 程序,看能否统计结果;若是能统计结果,表示代码可用。 以上就是整个验证的流程。 5.结束语 这篇文章就分享到这里,如果在验证的过程当中有什么问题,可以加群进行讨论或发送邮件给我,我会尽我所能为您解答,与君共勉! 联系方式: 邮箱:smartloli.org@gmail.com Twitter:https://twitter.com/smartloli QQ群(Hadoop - 交流社区1):424769183 温馨提示:请大家加群的时候写上加群理由(姓名+公司/学校),方便管理员审核,谢谢! 热爱生活,享受编程,与君共勉! 本文转自哥不是小萝莉博客园博客,原文链接:http://www.cnblogs.com/smartloli/,如需转载请自行联系原作者
概述: 在iOS中,可以使用剪贴板实现应用程序之中以及应用程序之间实现数据的共享。比如你可以从iPhone QQ复制一个url,然后粘贴到safari浏览器中查看这个链接的内容。 一、在iOS中下面三个控件,自身就有复制-粘贴的功能: 1、UITextView 2、UITextField 3、UIWebView 二、UIKit framework提供了几个类和协议方便我们在自己的应用程序中实现剪贴板的功能。 1、UIPasteboard:我们可以向其中写入数据,也可以读取数据 2、UIMenuController:显示一个快捷菜单,用来复制、剪贴、粘贴选择的项。 3、UIResponder中的 canPerformAction:withSender:用于控制哪些命令显示在快捷菜单中。 4、当快捷菜单上的命令点击的时候,UIResponderStandardEditActions将会被调用。 三、下面这些项能被放置到剪贴板中 1、UIPasteboardTypeListString — 字符串数组, 包含kUTTypeUTF8PlainText 2、UIPasteboardTypeListURL — URL数组,包含kUTTypeURL 3、UIPasteboardTypeListImage — 图形数组, 包含kUTTypePNG 和kUTTypeJPEG 4、UIPasteboardTypeListColor — 颜色数组 四、剪贴板的类型分为两种: 系统级:使用UIPasteboardNameGeneral和UIPasteboardNameFind创建,系统级的剪贴板,当应用程序关闭,或者卸载时,数据都不会丢失。 应用程序级:通过设置,可以让数据在应用程序关闭之后仍然保存在剪贴板中,但是应用程序卸载之后数据就会失去。我们可用通过pasteboardWithName:create:来创建。 了解这些之后,下面通过一系列的例子来说明如何在应用程序中使用剪贴板。 例子: 1、复制剪贴文本。 下面通过一个例子,可以在tableview上显示一个快捷菜单,上面只有复制按钮,复制tableview上的数据之后,然后粘贴到title上。 定义一个单元格类CopyTableViewCell,在这个类的上显示快捷菜单,实现复制功能。 @interface CopyTableViewCell : UITableViewCell {iddelegate; } @property (nonatomic, retain) iddelegate;@end 实现CopyTableViewCell : #import"CopyTableViewCell.h"@implementation CopyTableViewCell@synthesizedelegate;- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) { }return self; }- (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; }- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated { [[self delegate] performSelector:@selector(showMenu:) withObject:self afterDelay:0.9f]; [super setHighlighted:highlighted animated:animated]; }- (BOOL)canBecomeFirstResponder {return YES; }- (BOOL)canPerformAction:(SEL)action withSender:(id)sender{if (action == @selector(cut:)){return NO; } elseif(action == @selector(copy:)){return YES; } elseif(action == @selector(paste:)){return NO; } elseif(action == @selector(select:)){return NO; } elseif(action == @selector(selectAll:)){return NO; }else {return [super canPerformAction:action withSender:sender]; } }- (void)copy:(id)sender { UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; [pasteboard setString:[[self textLabel]text]]; }- (void)dealloc { [super dealloc]; }@end 定义CopyPasteTextController,实现粘贴功能。 @interface CopyPasteTextController : UIViewController<UITableViewDelegate> {//用来标识是否显示快捷菜单 BOOL menuVisible; UITableView *tableView; } @property (nonatomic, getter=isMenuVisible) BOOL menuVisible; @property (nonatomic, retain) IBOutlet UITableView *tableView;@end 实现CopyPasteTextController : #import"CopyPasteTextController.h"#import"CopyTableViewCell.h"@implementation CopyPasteTextController@synthesize menuVisible,tableView;- (void)viewDidLoad { [super viewDidLoad]; [self setTitle:@"文字复制粘贴"];//点击这个按钮将剪贴板的内容粘贴到title上 UIBarButtonItem *addButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(readFromPasteboard:)] autorelease]; [[self navigationItem] setRightBarButtonItem:addButton]; }// Customize the number of sections in the table view.- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {return1; }- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {return9; }// Customize the appearance of table view cells.- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {static NSString *CellIdentifier =@"Cell"; CopyTableViewCell *cell = (CopyTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];if (cell == nil) { cell = [[[CopyTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; [cell setDelegate:self]; }// Configure the cell. NSString *text = [NSString stringWithFormat:@"Row %d", [indexPath row]]; [[cell textLabel] setText:text];return cell; }- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {if([self isMenuVisible]) {return; } [[[self tableView] cellForRowAtIndexPath:indexPath] setSelected:YES animated:YES]; }//显示菜单- (void)showMenu:(id)cell {if ([cell isHighlighted]) { [cell becomeFirstResponder]; UIMenuController * menu = [UIMenuController sharedMenuController]; [menu setTargetRect: [cell frame] inView: [self view]]; [menu setMenuVisible: YES animated: YES]; } }- (void)readFromPasteboard:(id)sender { [self setTitle:[NSString stringWithFormat:@"Pasteboard = %@", [[UIPasteboard generalPasteboard] string]]]; }- (void)didReceiveMemoryWarning {// Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning];// Relinquish ownership any cached data, images, etc that aren't in use.}- (void)viewDidUnload { [super viewDidUnload]; [self.tableView release];// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.// For example: self.myOutlet = nil;} 效果: 复制一行数据: 点击右上角的按钮粘贴,将数据显示在title上: 2、图片复制粘贴 下面通过一个例子,将图片复制和剪贴到另外一个UIImageView中间。 1、在界面上放置两个uiimageview,一个是图片的数据源,一个是将图片粘贴到的地方。CopyPasteImageViewController 代码如下: @interface CopyPasteImageViewController : UIViewController { UIImageView *imageView; UIImageView *pasteView; UIImageView *selectedView; } @property (nonatomic, retain) IBOutlet UIImageView *imageView; @property (nonatomic, retain) IBOutlet UIImageView *pasteView; @property (nonatomic, retain) UIImageView *selectedView;- (void)placeImageOnPasteboard:(id)view;@end 2、当触摸图片的时候我们显示快捷菜单: - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { NSSet *copyTouches = [event touchesForView:imageView]; NSSet *pasteTouches = [event touchesForView:pasteView]; [self becomeFirstResponder];if ([copyTouches count] >0) { [self performSelector:@selector(showMenu:) withObject:imageView afterDelay:0.9f]; }elseif([pasteTouches count] >0) { [self performSelector:@selector(showMenu:) withObject:pasteView afterDelay:0.9f]; } [super touchesBegan:touches withEvent:event]; }- (void)showMenu:(id)view { [self setSelectedView:view]; UIMenuController * menu = [UIMenuController sharedMenuController]; [menu setTargetRect: CGRectMake(5, 10, 1, 1) inView: view]; [menu setMenuVisible: YES animated: YES]; } 这里的快捷菜单,显示三个菜单项:剪贴、粘贴、复制: - (BOOL)canPerformAction:(SEL)action withSender:(id)sender{if (action == @selector(cut:)) {return ([self selectedView] == imageView) ? YES : NO; } elseif (action == @selector(copy:)) {return ([self selectedView] == imageView) ? YES : NO; } elseif (action == @selector(paste:)) {return ([self selectedView] == pasteView) ? YES : NO; } elseif (action == @selector(select:)) {return NO; } elseif (action == @selector(selectAll:)) {return NO; } else {return [super canPerformAction:action withSender:sender]; } }- (void)cut:(id)sender { [self copy:sender]; [imageView setHidden:YES]; }- (void)copy:(id)sender { [self placeImageOnPasteboard:[self imageView]]; }- (void)paste:(id)sender { UIPasteboard *appPasteBoard = [UIPasteboard pasteboardWithName:@"CopyPasteImage" create:YES]; NSData *data =[appPasteBoard dataForPasteboardType:@"com.marizack.CopyPasteImage.imageView"]; pasteView.image = [UIImage imageWithData:data]; } 效果: 1、点击图片,显示菜单按钮。 2、点击复制,将数据复制到剪贴板上: 3、点击粘贴,将数据粘贴到uiimageview上。 总结:本文详解了iOS系统应用程序中如何使用剪贴板。 本文转自麒麟博客园博客,原文链接:http://www.cnblogs.com/zhuqil/archive/2011/08/04/2127883.html,如需转载请自行联系原作者