成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

iPhone SDK 多線程使用方法以及注意事項

移動開發 iOS
本文介紹的iPhone SDK 多線程使用方法以及注意事項,很詳細的解決了我們常見的一些問題,心來看內容。

iPhone SDK 多線程使用方法以及注意事項是本文要介紹的內容,不多說,直接進入話題。雖然現在大部分PC應用程序都支持多線程/多任務的開發方式,但是在iPhone上,Apple并不推薦使用多線程的編程方式。但是多線程編程畢竟是發展的趨勢,而且據說即將推出的iPhone OS4將全
 
雖然現在大部分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。如圖:

iPhone SDK 多線程使用方法以及注意事項

接下來,在 TutorialProjectViewController.h 文件中創建各個UI控件的 IBOutlets.

  1. @interface TutorialProjectViewController : UIViewController {  
  2.     // ------ Tutorial code starts here ------  
  3.     // Thread part  
  4.     IBOutlet UILabel *threadValueLabel;  
  5.     IBOutlet UIProgressView *threadProgressView;  
  6.     IBOutlet UIButton *threadStartButton;  
  7.     // Test part  
  8.     IBOutlet UILabel *testValueLabel;  
  9.     // ------ Tutorial code ends here ------  

同時,也需要創建outlets變量的property.

  1. @property (nonatomic, retain) IBOutlet UILabel *threadValueLabel;  
  2. @property (nonatomic, retain) IBOutlet UIProgressView *threadProgressView;  
  3. @property (nonatomic, retain) IBOutlet UIProgressView *threadStartButton;  
  4. @property (nonatomic, retain) IBOutlet UILabel *testValueLabel; 

接下來定義按鈕按下時的動作函數,以及slider的變化函數。

  1. - (IBAction) startThreadButtonPressed:(UIButton *)sender;  
  2. - (IBAction) testValueSliderChanged:(UISlider *)sender;  
  3. 然后在 TutorialProjectViewController.m 文件中synthesize outlets,并在文件為實現dealloc釋放資源。  
  4. @synthesize threadValueLabel, threadProgressView, testValueLabel, threadStartButton;  
  5. ...  
  6. - (void)dealloc {  
  7.     // ------ Tutorial code starts here ------  
  8.     [threadValueLabel release];  
  9.     [threadProgressView release];  
  10.     [threadStartButton release];  
  11.     [testValueLabel release];  
  12.     // ------ Tutorial code ends here ------  
  13.     [super dealloc];  

現在開始線程部分的代碼,首先當 thread button 被按下的時候,創建新的線程.

  1. - (IBAction) startThreadButtonPressed:(UIButton *)sender {  
  2.     threadStartButton.hidden = YES;  
  3.     threadValueLabel.text = @"0";  
  4.     threadProgressView.progress = 0.0;  
  5.     [NSThread detachNewThreadSelector:@selector(startTheBackgroundJob) toTarget:self withObject:nil];  

該按鈕被按下后,隱藏按鈕以禁止多次創建線程。然后初始化顯示值和進度條,最后創建新的線程,線程的函數為 startTheBackgroundJob。具體的 startTheBackgroundJob 函數定義如下.

  1. - (void)startTheBackgroundJob {  
  2.  
  3.     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  
  4.     // 線程開始后先暫停3秒(這里只是演示暫停的方法,你不是必須這么做的)  
  5.     [NSThread sleepForTimeInterval:3];  
  6.     [self performSelectorOnMainThread:@selector(makeMyProgressBarMoving) withObject:nil waitUntilDone:NO];  
  7.     [pool release];  

在第1行,創建了一個 NSAutoreleasePool 對象,用來管理線程中自動釋放的對象資源。這里 NSAutoreleasePool 在線程退出的時候釋放。這符合 Cocoa GUI 應用程序的一般規則。最后一行,阻塞調用(waitUntilDone狀態是ON)函數 makeMyProgressBarMoving。

  1. - (void)makeMyProgressBarMoving {  
  2.  
  3.     float actual = [threadProgressView progress];  
  4.     threadValueLabel.text = [NSString stringWithFormat:@"%.2f", actual];  
  5.     if (actual < 1) {  
  6.         threadProgressView.progress = actual + 0.01;  
  7.         [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(makeMyProgressBarMoving) userInfo:nil repeats:NO];  
  8.     }  
  9.     else threadStartButton.hidden = NO;  

這里計算用于顯示的進度條的值,利用 NSTimer ,每0.5秒自增0.01,當值等于1的時候,進度條為100%,退出函數并顯示剛才被隱藏的按鈕。

最后,添加 UISlider 的實現函數,用來更改主線程中 Test Part 中的 label 值。

  1. - (IBAction) testValueSliderChanged:(UISlider *)sender {  
  2. testValueLabel.text = [NSString stringWithFormat:@"%.2f", sender.value];  

編譯執行,按下線程開始按鈕,你將看到進度條的計算是在后臺運行。如圖:

iPhone SDK 多線程使用方法以及注意事項

使用線程的注意事項

線程的堆棧大小

iPhone設備上的應用程序開發也是屬于嵌入式設備的開發,同樣需要注意嵌入式設備開發時的幾點問題,比如資源上限,處理器速度等。

iPhone 中的線程應用并不是無節制的,官方給出的資料顯示iPhone OS下的主線程的堆棧大小是1M,第二個線程開始都是512KB。并且該值不能通過編譯器開關或線程API函數來更改。

你可以用下面的例子測試你的設備,這里使用POSIX Thread(pthread),設備環境是 iPhone 3GS(16GB)、SDK是3.1.3。 

  1. #include "pthread.h"  
  2.  
  3. void *threadFunc(void *arg) {  
  4.     void*  stack_base = pthread_get_stackaddr_np(pthread_self());  
  5.     size_t stack_size = pthread_get_stacksize_np(pthread_self());  
  6.     NSLog(@"Thread: base:%p / size:%u", stack_base, stack_size);  
  7.     return NULL;  
  8. }  
  9.  
  10. - (void)applicationDidFinishLaunching:(UIApplication *)application {  
  11.     void*  stack_base = pthread_get_stackaddr_np(pthread_self());  
  12.     size_t stack_size = pthread_get_stacksize_np(pthread_self());  
  13.     struct rlimit limit;  
  14.     getrlimit(RLIMIT_STACK, &limit);  
  15.     NSLog(@"Main thread: base:%p / size:%u", stack_base, stack_size);  
  16.     NSLog(@"  rlimit-> soft:%llu / hard:%llu", limit.rlim_cur, limit.rlim_max);  
  17.  
  18.     pthread_t thread;  
  19.     pthread_create(&thread, NULL, threadFunc, NULL);  
  20.  
  21.     // Override point for customization after app launch  
  22.     [window addSubview:viewController.view];  
  23.     [window makeKeyAndVisible];  

結果如下:

模擬器

  1. Main thread: base:0xc0000000 / size:524288  
  2. rlimit-> soft:8388608 / hard:67104768  
  3. Thread: base:0xb014b000 / size:524288 

設備

  1. Main thread: base:0x30000000 / size:524288  
  2. rlimit-> soft:1044480 / hard:1044480  
  3. Thread: base:0xf1000 / size:524288 

由此可見,當你測試多線程的程序時,模擬器和實際設備的堆棧大小是不一樣的。如果有大量遞歸函數調用可要注意了。

Autorelease

如果你什么都不考慮,在線程函數內調用 autorelease 、那么會出現下面的錯誤:

  1. NSAutoReleaseNoPool(): Object 0x********* of class NSConreteData autoreleased with no pool in place …. 

一般,在線程中使用內存的模式是,線程最初

  1. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; 

而在線程結束的時候 [pool drain] 或 [pool release]。

子線程中描畫窗口

多線程編程中普遍遵循一個原則,就是一切與UI相關的操作都有主線程做,子線程只負責事務,數據方面的處理。那么如果想在子線程中更新UI時怎么做呢?如果是在windows下,你會 PostMessage 一個描畫更新的消息,在iPhone中,需要使用performSelectorOnMainThread 委托主線程處理。

比如,如果在子線程中想讓 UIImageView 的 image 更新,如果直接在線程中

  1. imageView.image = [UIImage imageNamed:@"Hoge.png"]; 

這么做,什么也不會出現的。需要將該處理委托給主線程來做,像下面:

  1. [delegate performSelectorOnMainThread:@selector(theProcess:) withObject:nil waitUntilDone:YES]; 

就OK了!

小結:iPhone SDK多線程 使用方法以及注意事項的內容介紹完了,希望本文對你有所幫助。

轉自 http://www.yifeiyang.net/iphone-developer-advanced-11-multiple-threads-of-use-and-precautions/

責任編輯:zhaolei 來源: CocoaChina
相關推薦

2011-08-01 12:53:25

iPhone 多線程 線程

2011-06-14 15:25:28

C++多線程

2024-02-01 09:39:02

asyncawaitPromise

2011-07-25 17:48:10

iPhone 內存

2012-03-11 18:46:18

iPhone4S

2011-07-04 17:55:59

Qt SDK Windows

2025-04-03 07:33:56

2011-07-21 15:40:24

iPhone 內存管理 對象

2010-08-12 09:39:26

FlexaddChil

2010-07-27 14:17:52

Flex SDK4

2009-06-12 09:46:40

Java String

2017-04-06 09:49:55

Hive注意事項優化

2014-05-16 10:04:19

JavaScriptthis原理

2012-06-13 02:02:43

ServletJavaJSP

2011-07-06 11:13:29

iOS游戲開發

2010-11-26 16:27:01

MySQL使用變量

2010-01-18 14:25:19

使用C++Builde

2011-07-19 10:16:58

噴墨打印機注意事項

2022-09-23 09:25:04

代碼方法

2011-06-23 11:15:25

SEO網站優化
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩精品一区二区三区中文在线 | 久久婷婷麻豆国产91天堂 | 久久99精品久久久久久秒播九色 | 国产网站在线播放 | 日本免费一区二区三区四区 | 成人毛片视频免费 | 黄视频免费在线 | 亚洲免费在线播放 | 第一区在线观看免费国语入口 | 亚洲情视频 | 日韩在线91| 国产精品自在线 | 亚洲成人av | 国产一区二区自拍 | 一本一道久久a久久精品蜜桃 | 精品福利一区二区三区 | 婷婷激情综合 | 国产精品久久久久久久粉嫩 | 欧美色综合一区二区三区 | 国产欧美在线观看 | 日本免费小视频 | 日韩精品成人在线 | 日韩电影中文字幕 | 亚洲综合大片69999 | 午夜精品视频在线观看 | 久久国产日韩欧美 | 久久精品二区 | 欧美日韩综合 | 成人免费小视频 | av网址在线 | 久久精品亚洲精品国产欧美 | 日韩成人免费视频 | 亚洲黄色高清视频 | 亚洲欧美中文日韩在线v日本 | 欧美日韩成人在线 | 嫩草黄色影院 | 少妇av片 | 欧美一级网站 | 日韩精品一区二区三区四区视频 | 在线看片国产 | av看片|