1. 程式人生 > >淺談iOS中音訊的開發

淺談iOS中音訊的開發

  我對音訊技術不是很精通,最近對這方面比較有興趣,公司以前的專案用到這方面的技術不多。我只是粗略的涉獵沒有深入研究。今天就研究一下寫一篇部落格。同時希望以後能做一個關於音訊的商業專案也期望能接觸到音訊開發技術的大牛。

  隨著移動網際網路的發展,智慧手機功能越來越豐富。播放音樂、視訊、錄音、拍照等都是很常用的功能。在iOS中對於多媒體的支援是非常強大的,今天的文章中將會對音訊進行介紹。

  在iOS中音訊播放從形式上可以分為音效播放和音樂播放。前者主要指的是一些短音訊播放,通常作為點綴音訊,對於這類音訊不需要進行進度、迴圈等控制。後者指的是一些較長的音訊,通常是主音訊,對於這些音訊的播放通常需要進行精確的控制。在iOS中播放兩類音訊分別使用AudioToolbox.framework和AVFoundation.framework來完成音效和音樂播放。

  音效

 這裡我先介紹我做的一個專案,app名為“叮叮收銀”這是一個與收銀相關的專案。當時要做的效果是當收銀成功有一個“叮”的音效。這樣比較人性化,當時產品說會和老闆討論確定這個短音效。我當時就先考慮了短音訊的播放。不過後來我發現其實系統聲音完全可以。我當時聽了好多個系統聲音最後確定了一個大家都比較滿意的。不過測試聲音時要連線真機測試,模擬器是不可以的。

  下面是簡單示例:

 1.匯入#import <AudioToolbox/AudioToolbox.h>

 2.播放時呼叫AudioServicesPlaySystemSound(SystemSoundID);

 當引數為 1000-2000 之間數字時就是播放系統聲音(我的專案用的是1054音效)

 系統聲音對照表:

Sound ID File name (iPhone) File name (iPod Touch) Category Note
1000 new-mail.caf new-mail.caf MailReceived
1001 mail-sent.caf mail-sent.caf MailSent
1002 Voicemail.caf Voicemail.caf VoicemailReceived
1003 ReceivedMessage.caf ReceivedMessage.caf SMSReceived
1004 SentMessage.caf SentMessage.caf SMSSent
1005 alarm.caf sq_alarm.caf CalendarAlert
1006 low_power.caf low_power.caf LowPower
1007 sms-received1.caf sms-received1.caf SMSReceived_Alert
1008 sms-received2.caf sms-received2.caf SMSReceived_Alert
1009 sms-received3.caf sms-received3.caf SMSReceived_Alert
1010 sms-received4.caf sms-received4.caf SMSReceived_Alert
1011 - - SMSReceived_Vibrate
1012 sms-received1.caf sms-received1.caf SMSReceived_Alert
1013 sms-received5.caf sms-received5.caf SMSReceived_Alert
1014 sms-received6.caf sms-received6.caf SMSReceived_Alert
1015 Voicemail.caf Voicemail.caf - Available since 2.1
1016 tweet_sent.caf tweet_sent.caf SMSSent Available since 5.0
1020 Anticipate.caf Anticipate.caf SMSReceived_Alert Available since 4.2
1021 Bloom.caf Bloom.caf SMSReceived_Alert Available since 4.2
1022 Calypso.caf Calypso.caf SMSReceived_Alert Available since 4.2
1023 Choo_Choo.caf Choo_Choo.caf SMSReceived_Alert Available since 4.2
1024 Descent.caf Descent.caf SMSReceived_Alert Available since 4.2
1025 Fanfare.caf Fanfare.caf SMSReceived_Alert Available since 4.2
1026 Ladder.caf Ladder.caf SMSReceived_Alert Available since 4.2
1027 Minuet.caf Minuet.caf SMSReceived_Alert Available since 4.2
1028 News_Flash.caf News_Flash.caf SMSReceived_Alert Available since 4.2
1029 Noir.caf Noir.caf SMSReceived_Alert Available since 4.2
1030 Sherwood_Forest.caf Sherwood_Forest.caf SMSReceived_Alert Available since 4.2
1031 Spell.caf Spell.caf SMSReceived_Alert Available since 4.2
1032 Suspense.caf Suspense.caf SMSReceived_Alert Available since 4.2
1033 Telegraph.caf Telegraph.caf SMSReceived_Alert Available since 4.2
1034 Tiptoes.caf Tiptoes.caf SMSReceived_Alert Available since 4.2
1035 Typewriters.caf Typewriters.caf SMSReceived_Alert Available since 4.2
1036 Update.caf Update.caf SMSReceived_Alert Available since 4.2
1050 ussd.caf ussd.caf USSDAlert
1051 SIMToolkitCallDropped.caf SIMToolkitCallDropped.caf SIMToolkitTone
1052 SIMToolkitGeneralBeep.caf SIMToolkitGeneralBeep.caf SIMToolkitTone
1053 SIMToolkitNegativeACK.caf SIMToolkitNegativeACK.caf SIMToolkitTone
1054 SIMToolkitPositiveACK.caf SIMToolkitPositiveACK.caf SIMToolkitTone
1055 SIMToolkitSMS.caf SIMToolkitSMS.caf SIMToolkitTone
1057 Tink.caf Tink.caf PINKeyPressed
1070 ct-busy.caf ct-busy.caf AudioToneBusy There was no category for this sound before 4.0.
1071 ct-congestion.caf ct-congestion.caf AudioToneCongestion There was no category for this sound before 4.0.
1072 ct-path-ack.caf ct-path-ack.caf AudioTonePathAcknowledge There was no category for this sound before 4.0.
1073 ct-error.caf ct-error.caf AudioToneError There was no category for this sound before 4.0.
1074 ct-call-waiting.caf ct-call-waiting.caf AudioToneCallWaiting There was no category for this sound before 4.0.
1075 ct-keytone2.caf ct-keytone2.caf AudioToneKey2 There was no category for this sound before 4.0.
1100 lock.caf sq_lock.caf ScreenLocked
1101 unlock.caf sq_lock.caf ScreenUnlocked
1102 - - FailedUnlock
1103 Tink.caf sq_tock.caf KeyPressed
1104 Tock.caf sq_tock.caf KeyPressed
1105 Tock.caf sq_tock.caf KeyPressed
1106 beep-beep.caf sq_beep-beep.caf ConnectedToPower
1107 RingerChanged.caf RingerChanged.caf RingerSwitchIndication
1108 photoShutter.caf photoShutter.caf CameraShutter
1109 shake.caf shake.caf ShakeToShuffle Available since 3.0
1110 jbl_begin.caf jbl_begin.caf JBL_Begin Available since 3.0
1111 jbl_confirm.caf jbl_confirm.caf JBL_Confirm Available since 3.0
1112 jbl_cancel.caf jbl_cancel.caf JBL_Cancel Available since 3.0
1113 begin_record.caf begin_record.caf BeginRecording Available since 3.0
1114 end_record.caf end_record.caf EndRecording Available since 3.0
1115 jbl_ambiguous.caf jbl_ambiguous.caf JBL_Ambiguous Available since 3.0
1116 jbl_no_match.caf jbl_no_match.caf JBL_NoMatch Available since 3.0
1117 begin_video_record.caf begin_video_record.caf BeginVideoRecording Available since 3.0
1118 end_video_record.caf end_video_record.caf EndVideoRecording Available since 3.0
1150 vc~invitation-accepted.caf vc~invitation-accepted.caf VCInvitationAccepted Available since 4.0
1151 vc~ringing.caf vc~ringing.caf VCRinging Available since 4.0
1152 vc~ended.caf vc~ended.caf VCEnded Available since 4.0
1153 ct-call-waiting.caf ct-call-waiting.caf VCCallWaiting Available since 4.1
1154 vc~ringing.caf vc~ringing.caf VCCallUpgrade Available since 4.1
1200 dtmf-0.caf dtmf-0.caf TouchTone
1201 dtmf-1.caf dtmf-1.caf TouchTone
1202 dtmf-2.caf dtmf-2.caf TouchTone
1203 dtmf-3.caf dtmf-3.caf TouchTone
1204 dtmf-4.caf dtmf-4.caf TouchTone
1205 dtmf-5.caf dtmf-5.caf TouchTone
1206 dtmf-6.caf dtmf-6.caf TouchTone
1207 dtmf-7.caf dtmf-7.caf TouchTone
1208 dtmf-8.caf dtmf-8.caf TouchTone
1209 dtmf-9.caf dtmf-9.caf TouchTone
1210 dtmf-star.caf dtmf-star.caf TouchTone
1211 dtmf-pound.caf dtmf-pound.caf TouchTone
1254 long_low_short_high.caf long_low_short_high.caf Headset_StartCall
1255 short_double_high.caf short_double_high.caf Headset_Redial
1256 short_low_high.caf short_low_high.caf Headset_AnswerCall
1257 short_double_low.caf short_double_low.caf Headset_EndCall
1258 short_double_low.caf short_double_low.caf Headset_CallWaitingActions
1259 middle_9_short_double_low.caf middle_9_short_double_low.caf Headset_TransitionEnd
1300 Voicemail.caf Voicemail.caf SystemSoundPreview
1301 ReceivedMessage.caf ReceivedMessage.caf SystemSoundPreview
1302 new-mail.caf new-mail.caf SystemSoundPreview
1303 mail-sent.caf mail-sent.caf SystemSoundPreview
1304 alarm.caf sq_alarm.caf SystemSoundPreview
1305 lock.caf sq_lock.caf SystemSoundPreview
1306 Tock.caf sq_tock.caf KeyPressClickPreview The category was SystemSoundPreview before 3.2.
1307 sms-received1.caf sms-received1.caf SMSReceived_Selection
1308 sms-received2.caf sms-received2.caf SMSReceived_Selection
1309 sms-received3.caf sms-received3.caf SMSReceived_Selection
1310 sms-received4.caf sms-received4.caf SMSReceived_Selection
1311 - - SMSReceived_Vibrate
1312 sms-received1.caf sms-received1.caf SMSReceived_Selection
1313 sms-received5.caf sms-received5.caf SMSReceived_Selection
1314 sms-received6.caf sms-received6.caf SMSReceived_Selection
1315 Voicemail.caf Voicemail.caf SystemSoundPreview Available since 2.1
1320 Anticipate.caf Anticipate.caf SMSReceived_Selection Available since 4.2
1321 Bloom.caf Bloom.caf SMSReceived_Selection Available since 4.2
1322 Calypso.caf Calypso.caf SMSReceived_Selection Available since 4.2
1323 Choo_Choo.caf Choo_Choo.caf SMSReceived_Selection Available since 4.2
1324 Descent.caf Descent.caf SMSReceived_Selection Available since 4.2
1325 Fanfare.caf Fanfare.caf SMSReceived_Selection Available since 4.2
1326 Ladder.caf Ladder.caf SMSReceived_Selection Available since 4.2
1327 Minuet.caf Minuet.caf SMSReceived_Selection Available since 4.2
1328 News_Flash.caf News_Flash.caf SMSReceived_Selection Available since 4.2
1329 Noir.caf Noir.caf SMSReceived_Selection Available since 4.2
1330 Sherwood_Forest.caf Sherwood_Forest.caf SMSReceived_Selection Available since 4.2
1331 Spell.caf Spell.caf SMSReceived_Selection Available since 4.2
1332 Suspense.caf Suspense.caf SMSReceived_Selection Available since 4.2
1333 Telegraph.caf Telegraph.caf SMSReceived_Selection Available since 4.2
1334 Tiptoes.caf Tiptoes.caf SMSReceived_Selection Available since 4.2
1335 Typewriters.caf Typewriters.caf SMSReceived_Selection Available since 4.2
1336 Update.caf Update.caf SMSReceived_Selection Available since 4.2
1350 - - RingerVibeChanged
1351 - - SilentVibeChanged
4095 - - Vibrate There was no category for this sound before 2.2.
In the SDK this is the constant kSystemSoundID_Vibrate.

 AudioToolbox.framework是一套基於C語言的框架,使用它來播放音效其本質是將短音訊註冊到系統聲音服務(System Sound Service)。System Sound Service是一種簡單、底層的聲音播放服務,但是它本身也存在著一些限制:

 1. 音訊播放時間不能超過30s     

 2.資料必須是PCM或者IMA4格式    

 3.音訊檔案必須打包成.caf、.aif、.wav中的一種(注意這是官方文件的說法,實際測試發現一些.mp3也可以播放)

 使用System Sound Service 播放音效的步驟如下:

 1.呼叫AudioServicesCreateSystemSoundID(   CFURLRef  inFileURL, SystemSoundID*   outSystemSoundID)函式獲得系統聲音ID。

 2.如果需要監聽播放完成操作,則使用AudioServicesAddSystemSoundCompletion(  SystemSoundID inSystemSoundID,CFRunLoopRef  inRunLoop, CFStringRef  inRunLoopMode, AudioServicesSystemSoundCompletionProc  inCompletionRoutine, void*  inClientData)方法註冊回撥函式。

 3.呼叫AudioServicesPlaySystemSound(SystemSoundID inSystemSoundID) 或者AudioServicesPlayAlertSound(SystemSoundID inSystemSoundID) 方法播放音效(後者帶有震動效果)。】

 下面是簡單示例:

 1.匯入#import <AudioToolbox/AudioToolbox.h>

 2 .程式碼

 - (void)viewDidLoad{
    [super viewDidLoad];
    
    [self playSoundEffect:@"feedtip.wav"];
}

/**
 *  播放完成回撥函式
 *
 *  @param soundID    系統聲音ID
 *  @param clientData 回撥時傳遞的資料
 */
void soundCompleteCallback(SystemSoundID soundID,void * clientData){
    NSLog(@"播放完成...");
}

/**
 *  播放音效檔案
 *
 *  @param name 音訊檔名稱
 */
-(void)playSoundEffect:(NSString *)name{
    NSString *audioFile=[[NSBundle mainBundle] pathForResource:name ofType:nil];
    NSURL *fileUrl=[NSURL fileURLWithPath:audioFile];
    //1.獲得系統聲音ID
    SystemSoundID soundID = 0;
    /**
     * inFileUrl:音訊檔案url
     * outSystemSoundID:聲音id(此函式會將音效檔案加入到系統音訊服務中並返回一個長整形ID)
     */
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)(fileUrl), &soundID);
    //如果需要在播放完之後執行某些操作,可以呼叫如下方法註冊一個播放完成回撥函式
    AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, soundCompleteCallback, NULL);
    //2.播放音訊
    AudioServicesPlaySystemSound(soundID);//播放音效
    //    AudioServicesPlayAlertSound(soundID);//播放音效並震動
}

 音樂

 如果播放較大的音訊或者要對音訊有精確的控制則System Sound Service可能就很難滿足實際需求了,通常這種情況會選擇使用AVFoundation.framework中的AVAudioPlayer來實現。AVAudioPlayer可以看成一個播放器,它支援多種音訊格式,而且能夠進行進度、音量、播放速度等控制。首先簡單看一下AVAudioPlayer常用的屬性和方法:

屬性 說明
@property(readonly, getter=isPlaying) BOOL playing 是否正在播放,只讀
@property(readonly) NSUInteger numberOfChannels 音訊聲道數,只讀
@property(readonly) NSTimeInterval duration 音訊時長
@property(readonly) NSURL *url 音訊檔案路徑,只讀
@property(readonly) NSData *data 音訊資料,只讀
@property float pan 立體聲平衡,如果為-1.0則完全左聲道,如果0.0則左右聲道平衡,如果為1.0則完全為右聲道
@property float volume 音量大小,範圍0-1.0
@property BOOL enableRate 是否允許改變播放速率
@property float rate 播放速率,範圍0.5-2.0,如果為1.0則正常播放,如果要修改播放速率則必須設定enableRate為YES
@property NSTimeInterval currentTime 當前播放時長
@property(readonly) NSTimeInterval deviceCurrentTime 輸出裝置播放音訊的時間,注意如果播放中被暫停此時間也會繼續累加
@property NSInteger numberOfLoops 迴圈播放次數,如果為0則不迴圈,如果小於0則無限迴圈,大於0則表示迴圈次數
@property(readonly) NSDictionary *settings 音訊播放設定資訊,只讀
@property(getter=isMeteringEnabled) BOOL meteringEnabled 是否啟用音訊測量,預設為NO,一旦啟用音訊測量可以通過updateMeters方法更新測量值
物件方法 說明
- (instancetype)initWithContentsOfURL:(NSURL *)url error:(NSError **)outError 使用檔案URL初始化播放器,注意這個URL不能是HTTP URL,AVAudioPlayer不支援載入網路媒體流,只能播放本地檔案
- (instancetype)initWithData:(NSData *)data error:(NSError **)outError 使用NSData初始化播放器,注意使用此方法時必須檔案格式和檔案字尾一致,否則出錯,所以相比此方法更推薦使用上述方法或- (instancetype)initWithData:(NSData *)data fileTypeHint:(NSString *)utiString error:(NSError **)outError方法進行初始化
- (BOOL)prepareToPlay; 載入音訊檔案到緩衝區,注意即使在播放之前音訊檔案沒有載入到緩衝區程式也會隱式呼叫此方法。
- (BOOL)play; 播放音訊檔案
- (BOOL)playAtTime:(NSTimeInterval)time 在指定的時間開始播放音訊
- (void)pause; 暫停播放
- (void)stop; 停止播放
- (void)updateMeters 更新音訊測量值,注意如果要更新音訊測量值必須設定meteringEnabled為YES,通過音訊測量值可以即時獲得音訊分貝等資訊
- (float)peakPowerForChannel:(NSUInteger)channelNumber; 獲得指定聲道的分貝峰值,注意如果要獲得分貝峰值必須在此之前呼叫updateMeters方法
- (float)averagePowerForChannel:(NSUInteger)channelNumber 獲得指定聲道的分貝平均值,注意如果要獲得分貝平均值必須在此之前呼叫updateMeters方法
@property(nonatomic, copy) NSArray *channelAssignments 獲得或設定播放聲道
代理方法 說明
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag 音訊播放完成
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error 音訊解碼發生錯誤

 AVAudioPlayer的使用比較簡單:

  1. 初始化AVAudioPlayer物件,此時通常指定本地檔案路徑。
  2. 設定播放器屬性,例如重複次數、音量大小等。
  3. 呼叫play方法播放。
 當然由於AVAudioPlayer一次只能播放一個音訊檔案,所有上一曲、下一曲其實可以通過建立多個播放器物件來完成,這裡暫不實現。播放進度的實現主要依靠一個定時器實時計算當前播放時長和音訊總時長的比例,另外為了演示委託方法,下面的程式碼中也實現了播放完成委託方法,通常如果有下一曲功能的話播放完可以觸發下一曲音樂播放。下面是主要程式碼:

 1.匯入#import <AVFoundation/AVFoundation.h>
 今天有事先更到這裡。

 參考連結:http://www.cnblogs.com/kenshincui/p/4186022.html

相關推薦

iOS音訊開發

  我對音訊技術不是很精通,最近對這方面比較有興趣,公司以前的專案用到這方面的技術不多。我只是粗略的涉獵沒有深入研究。今天就研究一下寫一篇部落格。同時希望以後能做一個關於音訊的商業專案也期望能接觸到音

iOS的RunLoop

一段 ping itl rst 使用 http ram art 分享 首先解釋下為什麽是淺談,主要是RunLoop這個東西不單單是iOS的範疇,還涉及到操作系統,我指的淺談僅僅針對ios上層應用,底層的東西概不涉及 ,所以只能淺談淺談了。 在淺談RunLoop之前我們來寫個

iOS常用加密演算法的使用

 以前如果我們忘記了登入密碼,通常可以通過“找回密碼”這樣的方式拿回密碼,那說明你的隱私資料在他們的資料庫中是明文儲存的,現在請切記:如果哪個平臺還有這樣的方式請立刻馬上登出你的賬號,並避免在任何其他平臺使用這個平臺使用過的密碼。請堅信:在網路世界中,只要是明文存在或可逆的東西,都是不安全的。沒有哪家公司會告

iOS nil、Nil、null以及NSNull的區別

以下程式碼是直接在工程中驗證的,所以可以直接貼上到工程中檢視執行結果。 關於null的用法還不是太明確,歡迎交流。 //******************nil  Nil  null  NSNull**************     NSDictionary

iOS的迴圈引用問題

關於iOS中迴圈引用的場景: 1、代理 delegate      這個一般是不會出錯的,ARC建立代理的時候我們用的是weak,MRC下我們用的assign。基本就避免了這個問題。 2、block

iOS的閉包

1.1 用途        閉包在很多語言中都有應用,它在OC中被叫做Blocks,在Java中被叫做Lambda表示式,也有直接叫做匿名函式的。            簡單的說閉包就是一種帶有區域性變數的匿名函式。           在C語言中,函式可以通過函式名直接

iOS開發專案架構:iOS架構設計與分層

結構設計的層次是否越多越好? 多人都會說,凡事不能走極端,走了極端就過猶不及。所以應該分層,但不能過分分層,應該視具體情況來定。這樣的話聽起來很有道理,卻只是一句廢話。當我們遇到問題時,還是摸不著頭腦! 看看知名的架構師是怎麼說的吧!來自蔡學鏞 我做(開發)架構的幾個原則

Stingray的定製與開發

 上週剛剛開完了我們傳媒娛樂行業一年一度的開發者日活動,有不少朋友,尤其是一些設計領域的朋友也都對這個全新的遊戲引擎 Stingray比較感興趣。我們在會上也做了一些開發介紹,為了方便更多沒來參加的朋友,我也把這個簡單錄了個視訊放在這裡,大家可以一起探討。 (adsbygoo

Java的hashCode方法

implement state ask get() 存在 rsa key 沖突 如何 哈希表這個數據結構想必大多數人都不陌生,而且在很多地方都會利用到hash表來提高查找效率。在Java的Object類中有一個方法: public native int hashCode(

A1—JavaScript的原型(二)

js原型是什麽?想要了解這個問題,我們就必須要知道對象。對象根據w3cschool上的介紹:對象只是帶有屬性和方法的特殊數據類型。我們知道,數組是用來描述數據的。其實呢,對象也是用來描述數據的。只不過有一點點的區別,那就是數組的下標只能是數字。所以,數組最好只用來裝同樣意義的內容。比如說[1,2,3,4,5]

AngularJS的$parse和$eval

淺談 return 什麽是 apply() logs ava new 表達式 ret AngularJS的初學者常常會對$parse和$eval兩個內建服務感到有些困惑,今天我們就來說說AngularJS中的$parse和$eval。 總的來說,$parse和$eval都

AngularJS的指令和指令間的相互通信

file str 裏的 按鈕 相互 要去 direct 不能 pil 說到AngularJS,我們首先想到的大概也就是雙向數據綁定和指令系統了,這兩者也是AngularJS中最為吸引人的地方。雙向數據綁定呢,感覺沒什麽好說的,那麽今天我們就來簡單的討論下AngularJS這

springAOP以及springAOP的註解方式

早就 好的 面向 XML ram ati alt 返回 增強   AOP(Aspect Oriented Programming):AOP的專業術語是"面向切面編程" 什麽是面向切面編程,我的理解就是:在不修改源代碼的情況下增強功能.好了,下面在講述aop註解方式的情況下順

javascript的call與apply方法

分享 .cn ima his 修改 images 一個數 作用 undefine   call方法與apply方法都是為了改變函數體內部this的指向。   call方法與apply方法,這二者的作用完全一樣,只是接受參數的方式不太一樣。   apply()方法:  

遊戲BOSS設計的思路

移動 進程 經典 它的 操作技巧 時有 設計時 註意 有著 對於大多數遊戲來說,BOSS在其設計上都有著不可替代的作用,也是玩家印象最為深刻的一部分。近期自己也有在做BOSS的設計工作,有一些心得想要分享一下: 1.明確BOSS的設計目的 在設計之初,我們一定要想明白,設計

js的MVC

模擬 ner end i++ 反饋 mov 構架 als 觀察 MVC是什麽? MVC是一種架構模式,它將應用抽象為3個部分:模型(數據)、視圖、控制器(分發器) 本文將用一個經典的例子todoList來展開 一個事件發生的過程(通信單向流動): 1、用戶在視圖V上與應用

PHP的數組和JS的數組

例如 val pan exe png strong name 我們 sso 最近在做前後端對接的時候,遇到一個問題,前端要求返回的數據格式是左邊的,但是我通過json_encode返回到的數據格式是右邊的 註意:數據格式從"[]"(數組)變成了"{}"(對象)

java內置的觀察者模式與動態代理的實現

所有 代理 notify play ani effect 一個 indicate protected 一.關於觀察者模式 1.將觀察者與被觀察者分離開來,當被觀察者發生變化時,將通知所有觀察者,觀察者會根據這些變化做出對應的處理。 2.jdk裏已經提供對應的Observer

UML常用的幾種圖——用例圖

多個 spa log 分享 擴展 有關 包圖 可見 發的 1.UML簡介   統一建模語言(Unified Modeling Language,UML)又稱標準建模語言,是始於1997年的一個OMG標準,它是一個支持模型化和軟件系統開發的圖形化語言,為軟件開發的所有階段提供

Java的深拷貝和拷貝

detail tle pac err @override 復制對象 deep har 間接   淺談Java中的深拷貝和淺拷貝(轉載) 原文鏈接: http://blog.csdn.net/tounaobun/article/details/8491392 假如說你想復制一