当前位置: 编程技术>移动开发
本页文章导读:
▪在程序中施用GPS定位 在程序中使用GPS定位
这一回简单地介绍一下GPS的使用方法。使用GPS大致分下面两步。1.添加 CoreLocation.framework。2.生成 CLLocationManager 测量位置。测试代码如下:// LocationViewCtrl.h
#import <UIKi.........
▪ 多线程的施用与注意事项 多线程的使用与注意事项
多线程的使用与注意事项 这一回,主要介绍一下iPhone SDK中多线程的使用方法以及注意事项。虽然现在大部分PC应用程序都支持多线程/多任务的开发方式,但是在i.........
▪ ubuntu停连接真机进行调试的方法 ubuntu下连接真机进行调试的方法
连接方法: (1)ubuntu下,进入端末(Terminal),输入:sudo gedit /etc/udev/rules.d/50-android.rules,运行该命令打开文本编辑器。将下面这段文字粘贴上,保存。SUBSYS.........
[1]在程序中施用GPS定位
来源: 互联网 发布时间: 2014-02-18
在程序中使用GPS定位
这一回简单地介绍一下GPS的使用方法。使用GPS大致分下面两步。
1.添加 CoreLocation.framework。
2.生成 CLLocationManager 测量位置。
测试代码如下:
测量精度有以下几类,精度越高越消耗电力。
kCLLocationAccuracyNearestTenMeters 10m
kCLLocationAccuracyHundredMeters 100m
kCLLocationAccuracyKilometer 1km
kCLLocationAccuracyThreeKilometers 3km
因为在模拟器上不能设置经纬度,所以只能在实际设备中测试你的GPS程序。
这一回简单地介绍一下GPS的使用方法。使用GPS大致分下面两步。
1.添加 CoreLocation.framework。
2.生成 CLLocationManager 测量位置。
测试代码如下:
// LocationViewCtrl.h #import <UIKit/UIKit.h> #import <CoreLocation/CoreLocation.h> @interface LocationViewCtrl : UIViewController <CLLocationManagerDelegate>{ CLLocationManager *man; } @property(nonatomic, retain) CLLocationManager *man; @end LocationViewCtrl.m #import "LocationViewCtrl.h" #import <CoreLocation/CoreLocation.h> @implementation LocationViewCtrl @synthesize man; - (void)viewDidLoad { [super viewDidLoad]; man = [[CLLocationManager alloc] init]; // 如果可以利用本地服务时 if([man locationServicesEnabled]){ // 接收事件的实例 man.delegate = self; // 发生事件的的最小距离间隔(缺省是不指定) man.distanceFilter = kCLDistanceFilterNone; // 精度 (缺省是Best) man.desiredAccuracy = kCLLocationAccuracyBest; // 开始测量 [man startUpdatingLocation]; } } // 如果GPS测量成果以下的函数被调用 - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{ // 取得经纬度 CLLocationCoordinate2D coordinate = newLocation.coordinate; CLLocationDegrees latitude = coordinate.latitude; CLLocationDegrees longitude = coordinate.longitude; // 取得精度 CLLocationAccuracy horizontal = newLocation.horizontalAccuracy; CLLocationAccuracy vertical = newLocation.verticalAccuracy; // 取得高度 CLLocationDistance altitude = newLocation.altitude; // 取得时刻 NSDate *timestamp = [newLocation timestamp]; // 以下面的格式输出 format: <latitude>, <longitude>> +/- <accuracy>m @ <date-time> NSLog([newLocation description]); // 与上次测量地点的间隔距离 if(oldLocation != nil){ CLLocationDistance d = [newLocation getDistanceFrom:oldLocation]; NSLog([NSString stringWithFormat:@"%f", d]); } } // 如果GPS测量失败了,下面的函数被调用 - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{ NSLog([error localizedDescription]); } ...
测量精度有以下几类,精度越高越消耗电力。
kCLLocationAccuracyNearestTenMeters 10m
kCLLocationAccuracyHundredMeters 100m
kCLLocationAccuracyKilometer 1km
kCLLocationAccuracyThreeKilometers 3km
因为在模拟器上不能设置经纬度,所以只能在实际设备中测试你的GPS程序。
[2] 多线程的施用与注意事项
来源: 互联网 发布时间: 2014-02-18
多线程的使用与注意事项
多线程的使用与注意事项
这一回,主要介绍一下iPhone SDK中多线程的使用方法以及注意事项。虽然现在大部分PC应用程序都支持多线程/多任务的开发方式,但是在iPhone上,Apple并不推荐使用多线程的编程方式。但是多线程编程毕竟是发展的趋势,而且据说即将推出的iPhone OS4将全面支持多线程的处理方式。所以说掌握多线程的编程方式,在某些场合一定能挖掘出iPhone的更大潜力。
从例子入手
先从一个例程入手,具体的代码参考了这里。还有例程可以下载。
多线程程序的控制模型可以参考这里,一般情况下都是使用 管理者/工人模型, 这里,我们使用iPhone SDK中的 NSThread 来实现它。
首先创建一个新的 View-based application 工程,名字为 "TutorialProject" 。界面如下图所示,使用UILabel实现两部分的Part(Thread Part和Test Part),Thread Part中包含一个UIProgressView和一个UIButton;而Test Part包含一个值和一个UISlider。
接下来,在 TutorialProjectViewController.h 文件中创建各个UI控件的 IBOutlets.
同时,也需要创建outlets变量的property.
接下来定义按钮按下时的动作函数,以及slider的变化函数。
然后在 TutorialProjectViewController.m 文件中synthesize outlets,并在文件为实现dealloc释放资源。
现在开始线程部分的代码,首先当 thread button 被按下的时候,创建新的线程.
该按钮被按下后,隐藏按钮以禁止多次创建线程。然后初始化显示值和进度条,最后创建新的线程,线程的函数为 startTheBackgroundJob.
具体的 startTheBackgroundJob 函数定义如下.
在第1行,创建了一个 NSAutoreleasePool 对象,用来管理线程中自动释放的对象资源。这里 NSAutoreleasePool 在线程退出的时候释放。这符合 Cocoa GUI 应用程序的一般规则。
最后一行,阻塞调用(waitUntilDone状态是ON)函数 makeMyProgressBarMoving。
这里计算用于显示的进度条的值,利用 NSTimer ,每0.5秒自增0.01,当值等于1的时候,进度条为100%,退出函数并显示刚才被隐藏的按钮。
最后,添加 UISlider 的实现函数,用来更改主线程中 Test Part 中的 label 值
编译执行,按下线程开始按钮,你将看到进度条的计算是在后台运行。
使用线程的注意事项
线程的堆栈大小iPhone设备上的应用程序开发也是属于嵌入式设备的开发,同样需要注意嵌入式设备开发时的几点问题,比如资源上限,处理器速度等。
iPhone 中的线程应用并不是无节制的,官方给出的资料显示iPhone OS下的主线程的堆栈大小是1M,第二个线程开始都是512KB。并且该值不能通过编译器开关或线程API函数来更改。
你可以用下面的例子测试你的设备,这里使用POSIX Thread(pthread),设备环境是 iPhone 3GS(16GB)、SDK是3.1.3。
结果如下:
模拟器
Main thread: base:0xc0000000 / size:524288
rlimit-> soft:8388608 / hard:67104768
Thread: base:0xb014b000 / size:524288
设备
Main thread: base:0x30000000 / size:524288
rlimit-> soft:1044480 / hard:1044480
Thread: base:0xf1000 / size:524288
由此可见,当你测试多线程的程序时,模拟器和实际设备的堆栈大小是不一样的。如果有大量递归函数调用可要注意了。
Autorelease
如果你什么都不考虑,在线程函数内调用 autorelease 、那么会出现下面的错误:
一般,在线程中使用内存的模式是,线程最初
而在线程结束的时候 [pool drain] 或 [pool release]。<sup><a name="fnr.1" href="#fn.1">1.</a></sup>
子线程中描画窗口
多线程编程中普遍遵循一个原则,就是一切与UI相关的操作都有主线程做,子线程只负责事务,数据方面的处理。那么如果想在子线程中更新UI时怎么做呢?如果是在windows下,你会 PostMessage 一个描画更新的消息,在iPhone中,需要使用performSelectorOnMainThread 委托主线程处理。
比如,如果在子线程中想让 UIImageView 的 image 更新,如果直接在线程中
这么做,什么也不会出现的。需要将该处理委托给主线程来做,像下面:
就OK了
<a name="fn.1" href="#fnr.1">1.</a> drain 与 release 的区别前提是你的系统中是否有GC,如果有,-drain 需要送一个消息给GC (objc_collect_if_needed),而如果没有GC,drain = release
多线程的使用与注意事项
这一回,主要介绍一下iPhone SDK中多线程的使用方法以及注意事项。虽然现在大部分PC应用程序都支持多线程/多任务的开发方式,但是在iPhone上,Apple并不推荐使用多线程的编程方式。但是多线程编程毕竟是发展的趋势,而且据说即将推出的iPhone OS4将全面支持多线程的处理方式。所以说掌握多线程的编程方式,在某些场合一定能挖掘出iPhone的更大潜力。
从例子入手
先从一个例程入手,具体的代码参考了这里。还有例程可以下载。
多线程程序的控制模型可以参考这里,一般情况下都是使用 管理者/工人模型, 这里,我们使用iPhone SDK中的 NSThread 来实现它。
首先创建一个新的 View-based application 工程,名字为 "TutorialProject" 。界面如下图所示,使用UILabel实现两部分的Part(Thread Part和Test Part),Thread Part中包含一个UIProgressView和一个UIButton;而Test Part包含一个值和一个UISlider。
接下来,在 TutorialProjectViewController.h 文件中创建各个UI控件的 IBOutlets.
@interface TutorialProjectViewController : UIViewController { // ------ Tutorial code starts here ------ // Thread part IBOutlet UILabel *threadValueLabel; IBOutlet UIProgressView *threadProgressView; IBOutlet UIButton *threadStartButton; // Test part IBOutlet UILabel *testValueLabel; // ------ Tutorial code ends here ------ }
同时,也需要创建outlets变量的property.
@property (nonatomic, retain) IBOutlet UILabel *threadValueLabel; @property (nonatomic, retain) IBOutlet UIProgressView *threadProgressView; @property (nonatomic, retain) IBOutlet UIProgressView *threadStartButton; @property (nonatomic, retain) IBOutlet UILabel *testValueLabel;
接下来定义按钮按下时的动作函数,以及slider的变化函数。
- (IBAction) startThreadButtonPressed:(UIButton *)sender; - (IBAction) testValueSliderChanged:(UISlider *)sender;
然后在 TutorialProjectViewController.m 文件中synthesize outlets,并在文件为实现dealloc释放资源。
@synthesize threadValueLabel, threadProgressView, testValueLabel, threadStartButton; ... - (void)dealloc { // ------ Tutorial code starts here ------ [threadValueLabel release]; [threadProgressView release]; [threadStartButton release]; [testValueLabel release]; // ------ Tutorial code ends here ------ [super dealloc]; }
现在开始线程部分的代码,首先当 thread button 被按下的时候,创建新的线程.
- (IBAction) startThreadButtonPressed:(UIButton *)sender { threadStartButton.hidden = YES; threadValueLabel.text = @"0"; threadProgressView.progress = 0.0; [NSThread detachNewThreadSelector:@selector(startTheBackgroundJob) toTarget:self withObject:nil]; }
该按钮被按下后,隐藏按钮以禁止多次创建线程。然后初始化显示值和进度条,最后创建新的线程,线程的函数为 startTheBackgroundJob.
具体的 startTheBackgroundJob 函数定义如下.
- (void)startTheBackgroundJob { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // 线程开始后先暂停3秒(这里只是演示暂停的方法,你不是必须这么做的) [NSThread sleepForTimeInterval:3]; [self performSelectorOnMainThread:@selector(makeMyProgressBarMoving) withObject:nil waitUntilDone:NO]; [pool release]; }
在第1行,创建了一个 NSAutoreleasePool 对象,用来管理线程中自动释放的对象资源。这里 NSAutoreleasePool 在线程退出的时候释放。这符合 Cocoa GUI 应用程序的一般规则。
最后一行,阻塞调用(waitUntilDone状态是ON)函数 makeMyProgressBarMoving。
- (void)makeMyProgressBarMoving { float actual = [threadProgressView progress]; threadValueLabel.text = [NSString stringWithFormat:@"%.2f", actual]; if (actual < 1) { threadProgressView.progress = actual + 0.01; [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(makeMyProgressBarMoving) userInfo:nil repeats:NO]; } else threadStartButton.hidden = NO; }
这里计算用于显示的进度条的值,利用 NSTimer ,每0.5秒自增0.01,当值等于1的时候,进度条为100%,退出函数并显示刚才被隐藏的按钮。
最后,添加 UISlider 的实现函数,用来更改主线程中 Test Part 中的 label 值
- (IBAction) testValueSliderChanged:(UISlider *)sender { testValueLabel.text = [NSString stringWithFormat:@"%.2f", sender.value]; }
编译执行,按下线程开始按钮,你将看到进度条的计算是在后台运行。
使用线程的注意事项
线程的堆栈大小iPhone设备上的应用程序开发也是属于嵌入式设备的开发,同样需要注意嵌入式设备开发时的几点问题,比如资源上限,处理器速度等。
iPhone 中的线程应用并不是无节制的,官方给出的资料显示iPhone OS下的主线程的堆栈大小是1M,第二个线程开始都是512KB。并且该值不能通过编译器开关或线程API函数来更改。
你可以用下面的例子测试你的设备,这里使用POSIX Thread(pthread),设备环境是 iPhone 3GS(16GB)、SDK是3.1.3。
#include "pthread.h" void *threadFunc(void *arg) { void* stack_base = pthread_get_stackaddr_np(pthread_self()); size_t stack_size = pthread_get_stacksize_np(pthread_self()); NSLog(@"Thread: base:%p / size:%u", stack_base, stack_size); return NULL; } - (void)applicationDidFinishLaunching:(UIApplication *)application { void* stack_base = pthread_get_stackaddr_np(pthread_self()); size_t stack_size = pthread_get_stacksize_np(pthread_self()); struct rlimit limit; getrlimit(RLIMIT_STACK, &limit); NSLog(@"Main thread: base:%p / size:%u", stack_base, stack_size); NSLog(@" rlimit-> soft:%llu / hard:%llu", limit.rlim_cur, limit.rlim_max); pthread_t thread; pthread_create(&thread, NULL, threadFunc, NULL); // Override point for customization after app launch [window addSubview:viewController.view]; [window makeKeyAndVisible]; }
结果如下:
模拟器
Main thread: base:0xc0000000 / size:524288
rlimit-> soft:8388608 / hard:67104768
Thread: base:0xb014b000 / size:524288
设备
Main thread: base:0x30000000 / size:524288
rlimit-> soft:1044480 / hard:1044480
Thread: base:0xf1000 / size:524288
由此可见,当你测试多线程的程序时,模拟器和实际设备的堆栈大小是不一样的。如果有大量递归函数调用可要注意了。
Autorelease
如果你什么都不考虑,在线程函数内调用 autorelease 、那么会出现下面的错误:
NSAutoReleaseNoPool(): Object 0x********* of class NSConreteData autoreleased with no pool in place ….
一般,在线程中使用内存的模式是,线程最初
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
而在线程结束的时候 [pool drain] 或 [pool release]。<sup><a name="fnr.1" href="#fn.1">1.</a></sup>
子线程中描画窗口
多线程编程中普遍遵循一个原则,就是一切与UI相关的操作都有主线程做,子线程只负责事务,数据方面的处理。那么如果想在子线程中更新UI时怎么做呢?如果是在windows下,你会 PostMessage 一个描画更新的消息,在iPhone中,需要使用performSelectorOnMainThread 委托主线程处理。
比如,如果在子线程中想让 UIImageView 的 image 更新,如果直接在线程中
imageView.image = [UIImage imageNamed:@"Hoge.png"];
这么做,什么也不会出现的。需要将该处理委托给主线程来做,像下面:
[delegate performSelectorOnMainThread:@selector(theProcess:) withObject:nil waitUntilDone:YES];
就OK了
<a name="fn.1" href="#fnr.1">1.</a> drain 与 release 的区别前提是你的系统中是否有GC,如果有,-drain 需要送一个消息给GC (objc_collect_if_needed),而如果没有GC,drain = release
[3] ubuntu停连接真机进行调试的方法
来源: 互联网 发布时间: 2014-02-18
ubuntu下连接真机进行调试的方法
连接方法:
(1)ubuntu下,进入端末(Terminal),输入:
sudo gedit /etc/udev/rules.d/50-android.rules
,运行该命令打开文本编辑器。
将下面这段文字粘贴上,保存。
SUBSYSTEM=="usb", SYSFS{idVendor}=="0bb4", MODE="0666"
继续在端末执行:
sudo chmod a+rx /etc/udev/rules.d/50-android.rules
进入android-sdk中的tools目录
执行sudo ./adb kill-server
再执行 sudo ./adb devices
显示出真机设备的编号表明连接成功。
(2) 进入eclipse,在project explorer中右键点击要安装的工程->Run As->Run Configurations,把运行的target修改为手动(Manual)。
然后Run,这时会提示选择目标,选择真机即可。(没有显示出真机时,试试将usb线拔掉再插上)
如果顺利,不一会儿手机屏幕上就会出现刚刚安装的android应用程序了。
连接方法:
(1)ubuntu下,进入端末(Terminal),输入:
sudo gedit /etc/udev/rules.d/50-android.rules
,运行该命令打开文本编辑器。
将下面这段文字粘贴上,保存。
SUBSYSTEM=="usb", SYSFS{idVendor}=="0bb4", MODE="0666"
继续在端末执行:
sudo chmod a+rx /etc/udev/rules.d/50-android.rules
进入android-sdk中的tools目录
执行sudo ./adb kill-server
再执行 sudo ./adb devices
显示出真机设备的编号表明连接成功。
(2) 进入eclipse,在project explorer中右键点击要安装的工程->Run As->Run Configurations,把运行的target修改为手动(Manual)。
然后Run,这时会提示选择目标,选择真机即可。(没有显示出真机时,试试将usb线拔掉再插上)
如果顺利,不一会儿手机屏幕上就会出现刚刚安装的android应用程序了。
最新技术文章: