錄制wav格式的音頻

項目中有面部認證、聲紋認證,服務器端要求上傳wav格式的音頻,所以寫了這樣一個小demo。

剛剛開始寫博客還不知道怎么上傳代碼,就復制了,嘻嘻

DotimeManage.h


@class DotimeManage;

@protocol DotimeManageDelegate <NSObject>


- (void)TimerActionValueChange:(int)time; //時間改變


@end

#import <Foundation/Foundation.h>


@interface DotimeManage : NSObject

{

? ? NSTimer *BBtimer;

}

@property (nonatomic)int timeValue;

@property (nonatomic,assign)id<DotimeManageDelegate> delegate;

+ (DotimeManage *)DefaultManage;


//開始計時

- (void)startTime;


//停止計時

- (void)stopTimer;

@end




DotimeManage.m


#import "DotimeManage.h"


@implementation DotimeManage

static DotimeManage *timeManage = nil;

+ (DotimeManage *)DefaultManage{

? ? static dispatch_once_t onceToken;

? ? dispatch_once(&onceToken, ^{

? ? ? ? timeManage = [[DotimeManage alloc] init];

? ? });

? ? return timeManage;

}

- (id)init {

? ? self = [super init];

? ? if (self) {


? ? }

? ? return self;

}


//開始計時

- (void)startTime {

? ? //停止上次計時器

? ? [self stopTimer];

?? ?

? ? if (BBtimer == nil) {

? ? ? ? self.timeValue = 0;

? ? ? ? BBtimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(TimerAction) userInfo:nil repeats:YES];

? ? ? ? NSRunLoop *main=[NSRunLoop currentRunLoop];

? ? ? ? [main addTimer:BBtimer forMode:NSRunLoopCommonModes];

? ? }

}


//停止計時

- (void)stopTimer {

? ? if (BBtimer != nil) {

? ? ? ? [BBtimer invalidate];

? ? ? ? BBtimer = nil;

? ? }

}


//倒計時

- (void)TimerAction {

? ? self.timeValue ++;

? ? if ([self.delegate respondsToSelector:@selector(TimerActionValueChange:)]) {

? ? ? ? [self.delegate TimerActionValueChange:self.timeValue];

? ? }

}

@end




Recorder.h


#import <Foundation/Foundation.h>

#import <AVFoundation/AVFoundation.h>

#import <AudioToolbox/AudioToolbox.h>

#import <UIKit/UIKit.h>


#define DefaultSubPath @"Voice" //默認 二級目錄 可以修改自己想要的 例如 "文件夾1/文件夾2/文件夾3"


#define SampleRateKey 44100.0 //采樣率8000.0

#define LinearPCMBitDepth 16 //采樣位數 默認 16

#define NumberOfChannels 1? //通道的數目


@protocol RecorderDelegate <NSObject>

/**

?* 錄音進行中

?* currentTime 錄音時長

?**/

-(void)recorderCurrentTime:(NSTimeInterval)currentTime;


/**

?* 錄音完成

?* filePath 錄音文件保存路徑

?* fileName 錄音文件名

?* duration 錄音時長

?**/

-(void)recorderStop:(NSString *)filePath voiceName:(NSString *)fileName duration:(NSTimeInterval)duration;


/**

?* 開始錄音

?**/

-(void)recorderStart;

@end


@interface Recorder : NSObject<AVAudioRecorderDelegate>


@property (assign, nonatomic) id<RecorderDelegate> recorderDelegate;

@property(strong, nonatomic) NSString *filename,*filePath;

/**

?* 錄音控件 單例對象

?**/

+(Recorder *)shareRecorder;



/**

?* 開始錄音

?* //默認的錄音存儲的文件夾在 "Document/Voice/文件名(文件名示例: 2015-01-06_12:41).wav"

?* 錄音的文件名 "2015-01-06_12:41"

?**/

-(void)startRecord;

/**

?* 停止錄音

?**/

-(void)stopRecord;


/**

?* 獲得峰值

?**/

-(float)getPeakPower;


/**

?* 是否可以錄音

?**/

- (BOOL)canRecord;



@end


Recorder.m

#import "Recorder.h"



#ifdef DEBUG

#define VSLog(log, ...) NSLog(log, ## __VA_ARGS__)

#else

#define VSLog(log, ...)

#endif

#define IOS7 ? ( [[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending )



@interface Recorder ()

{

? ? NSMutableArray *cacheDelegates;

? ? NSMutableArray *cacheURLs;

? ? NSTimer ? ? *countDownTimer_;//定時器,每秒調用一次

}


@property(strong, nonatomic) AVAudioRecorder *audioRecorder;


@property(strong, nonatomic) NSMutableDictionary *cacheDic;


@end


@implementation Recorder

+(Recorder *)shareRecorder

{

? ? static Recorder *sharedRecorderInstance = nil;

? ? static dispatch_once_t predicate;

? ? dispatch_once(&predicate, ^{

? ? ? ? sharedRecorderInstance = [[self alloc] init];

? ? });

? ? return sharedRecorderInstance;

}


-(BOOL)canRecord

{

? ? __block BOOL bCanRecord = YES;

? ? if (IOS7)

? ? {

? ? ? ? AVAudioSession *audioSession = [AVAudioSession sharedInstance];

? ? ? ? if ([audioSession respondsToSelector:@selector(requestRecordPermission:)]) {

? ? ? ? ? ? [audioSession performSelector:@selector(requestRecordPermission:) withObject:^(BOOL granted) {

? ? ? ? ? ? ? ? if (granted) {

? ? ? ? ? ? ? ? ? ? bCanRecord = YES;

? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? bCanRecord = NO;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }];

? ? ? ? }

? ? }

?? ?

? ? return bCanRecord;

}



-(id)init

{

? ? self = [super init];

? ? if (self) {

? ? ? ? self.cacheDic = [NSMutableDictionary dictionaryWithCapacity:1];

? ? ? ? cacheDelegates = [[NSMutableArray alloc] init];

? ? ? ? cacheURLs = [[NSMutableArray alloc] init];

? ? ? ? [self resetTimerCount];

? ? }

? ? return self;

}


-(void)stopTimerCountRun

{

? ? if (countDownTimer_) {

? ? ? ? [countDownTimer_ invalidate];

? ? ? ? countDownTimer_ = nil;

? ? }

}

-(void)resetTimerCount

{

? ? [self stopTimerCountRun];

? ? countDownTimer_ = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timeCountDown) userInfo:nil repeats:YES];

? ? [[NSRunLoop currentRunLoop] addTimer:countDownTimer_ forMode:NSRunLoopCommonModes];

}

- (void)timeCountDown

{

? ? if (self.audioRecorder.isRecording) {

? ? ? ? //當前時間

? ? ? ? if ([self.recorderDelegate respondsToSelector:@selector(recorderCurrentTime:)]) {

? ? ? ? ? ? [self.recorderDelegate recorderCurrentTime:self.audioRecorder.currentTime];

? ? ? ? }

? ? }

}

#pragma mark - 廣播停止錄音

//停止錄音

-(void)stopAVAudioRecord

{

?? ?

}

-(void)startRecordWithFilePath:(NSString *)filePath

{

?? ?

? ? AVAudioSession *session = [AVAudioSession sharedInstance];

?? ?

? ? [session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];

? ? [session setActive:YES error:nil];

?? ?

? ? NSDictionary *recordSetting = [NSDictionary dictionaryWithObjectsAndKeys:

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [NSNumber numberWithFloat: SampleRateKey],AVSampleRateKey, //采樣率

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [NSNumber numberWithInt: kAudioFormatLinearPCM],AVFormatIDKey,

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [NSNumber numberWithInt:LinearPCMBitDepth],AVLinearPCMBitDepthKey,//采樣位數 默認 16

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [NSNumber numberWithInt: NumberOfChannels], AVNumberOfChannelsKey,//通道的數目,

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nil];

?? ?

?? ?

? ? NSURL *url = [NSURL fileURLWithPath:filePath];

? ? self.filePath = filePath;

?? ?

? ? NSError *error = nil;

? ? if (self.audioRecorder) {

? ? ? ? if (self.audioRecorder.isRecording) {

? ? ? ? ? ? [self.audioRecorder stop];

? ? ? ? }

? ? ? ? self.audioRecorder = nil;

? ? }

?? ?

? ? AVAudioRecorder *tmpRecord = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&error];

? ? self.audioRecorder = tmpRecord;

? ? self.audioRecorder.meteringEnabled = YES;

? ? self.audioRecorder.delegate = self;

? ? if ([self.audioRecorder prepareToRecord] == YES){

? ? ? ? self.audioRecorder.meteringEnabled = YES;

? ? ? ? [self.audioRecorder record];

? ? ? ? if ([self.recorderDelegate respondsToSelector:@selector(recorderStart)]) {

? ? ? ? ? ? [self.recorderDelegate recorderStart];

? ? ? ? }

? ? ? ? [[UIApplication sharedApplication] setIdleTimerDisabled: YES];//保持屏幕長亮

? ? ? ? [[UIDevice currentDevice] setProximityMonitoringEnabled:NO]; //建議在播放之前設置yes,播放結束設置NO,這個功能是開啟紅外感應

?? ? ? ?

? ? }else {

? ? ? ? int errorCode = CFSwapInt32HostToBig ([error code]);

? ? ? ? VSLog(@"Error: %@ [%4.4s])" , [error localizedDescription], (char*)&errorCode);

?? ? ? ?

? ? }

}

-(void)startRecord

{

? ? NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NSDocumentDirectory, NSUserDomainMask, YES);

? ? NSString *docsDir = [dirPaths objectAtIndex:0];

? ? //錄音文件名采用時間標記 例如"2015-01-06_12:41"

//? ? self.filename = [self createFilename];

? ? self.filename = @"RecordingFile";

? ? NSString *soundFilePath = [docsDir

?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? stringByAppendingPathComponent:[NSString stringWithFormat:@"%@/%@.wav",DefaultSubPath,self.filename]];

?? ?

? ? [self createFilePath];

? ? [self startRecordWithFilePath:soundFilePath];

}


//創建錄音文件名字

- (NSString *)createFilename {

? ? NSDate *date_ = [NSDate date];

? ? NSDateFormatter *dateformater = [[NSDateFormatter alloc] init];

? ? [dateformater setDateFormat:@"yyyy-MM-dd_HH-mm-ss"];

? ? NSString *timeFileName = [dateformater stringFromDate:date_];

? ? return timeFileName;

}

//創建存儲路徑

-(void)createFilePath

{

? ? NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NSDocumentDirectory, NSUserDomainMask, YES);

? ? NSString *docsDir = [dirPaths objectAtIndex:0];

? ? NSString *savedImagePath = [docsDir

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? stringByAppendingPathComponent:DefaultSubPath];

? ? BOOL isDir = NO;

? ? NSFileManager *fileManager = [NSFileManager defaultManager];

? ? BOOL existed = [fileManager fileExistsAtPath:savedImagePath isDirectory:&isDir];

? ? if ( !(isDir == YES && existed == YES) )

? ? {

? ? ? ? [fileManager createDirectoryAtPath:savedImagePath withIntermediateDirectories:YES attributes:nil error:nil];

? ? }

}



-(void)stopRecord

{

? ? if (self.audioRecorder) {

? ? ? ? if ([self.recorderDelegate respondsToSelector:@selector(recorderStop:voiceName:duration:)]) {

? ? ? ? ? ? [self.recorderDelegate recorderStop:self.filePath voiceName:self.filename duration:self.audioRecorder.currentTime];

? ? ? ? }

? ? ? ? self.recorderDelegate = nil;

? ? ? ? [self.audioRecorder stop];

?? ? ? ?

? ? ? ? AVAudioSession *session = [AVAudioSession sharedInstance];

? ? ? ? [session setActive:NO error:nil];

? ? ? ? [session setCategory:AVAudioSessionCategoryAmbient error:nil];

? ? }

}

-(float)getPeakPower

{

? ? [self.audioRecorder updateMeters];

? ? float linear = pow (10, [self.audioRecorder peakPowerForChannel:0] / 20);

? ? float linear1 = pow (10, [self.audioRecorder averagePowerForChannel:0] / 20);

? ? float Pitch = 0;

? ? if (linear1>0.03) {

?? ? ? ?

? ? ? ? Pitch = linear1+.20;//pow (10, [audioRecorder averagePowerForChannel:0] / 20);//[audioRecorder peakPowerForChannel:0];

? ? }

? ? else {

?? ? ? ?

? ? ? ? Pitch = 0.0;

? ? }

? ? float peakPowerForChannel = (linear + 160)/160;

? ? return peakPowerForChannel;

}


//-(void)dealloc

//{

//? ? self.audioRecorder = nil;

//? ? [[NSNotificationCenter defaultCenter] removeObserver:self];

//? ? [super dealloc];

//}

//

#pragma mark -

#pragma mark AVAudioRecorderDelegate Methods

-(void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag

{

? ? [[UIApplication sharedApplication] setIdleTimerDisabled: NO];

? ? if (flag) {

? ? ? ? if ([self.recorderDelegate respondsToSelector:@selector(recorderStop:voiceName:duration:)]) {

? ? ? ? ? ? [self.recorderDelegate recorderStop:self.filePath voiceName:self.filename duration:self.audioRecorder.currentTime];

? ? ? ? }

? ? ? ? self.recorderDelegate = nil;

? ? }else{

? ? ? ? if ([self.recorderDelegate respondsToSelector:@selector(recorderStop:voiceName:duration:)]) {

? ? ? ? ? ? [self.recorderDelegate recorderStop:self.filePath voiceName:self.filename duration:self.audioRecorder.currentTime];

? ? ? ? }

? ? ? ? self.recorderDelegate = nil;

? ? }

? ? AVAudioSession *session = [AVAudioSession sharedInstance];

? ? [session setActive:NO error:nil];

? ? [session setCategory:AVAudioSessionCategoryAmbient error:nil];

}

-(void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error

{

? ? [[UIApplication sharedApplication] setIdleTimerDisabled: NO];

?? ?

? ? if ([self.recorderDelegate respondsToSelector:@selector(recorderStop:voiceName:duration:)]) {

? ? ? ? [self.recorderDelegate recorderStop:self.filePath voiceName:self.filename duration:self.audioRecorder.currentTime];

? ? }

? ? self.recorderDelegate = nil;

? ? AVAudioSession *session = [AVAudioSession sharedInstance];

? ? [session setActive:NO error:nil];

? ? [session setCategory:AVAudioSessionCategoryAmbient error:nil];

}


@end



在需要錄制音頻的界面調用這兩個文件

錄制音頻的按鈕有兩個響應事件,代碼如下

[recordingBtn addTarget:self action:@selector(buttonSayBegin) forControlEvents:UIControlEventTouchDown];

? ? [recordingBtn addTarget:self action:@selector(buttonSayEnd) forControlEvents:UIControlEventTouchUpInside];


- (void)buttonSayBegin

{

? ? [self stopAudio];

?? ?

? ? [[Recorder shareRecorder]startRecord];

??

}


- (void)buttonSayEnd

{ ? ?

? ? [[Recorder shareRecorder]stopRecord];

?? ?

? ? [self stopAudio];

?? ?

? ? //? ? [StateLable setText:@"播放錄音文件中。。"];

? ? NSString * string = [Recorder shareRecorder].filePath;

? ? [self playAudio:string];


}


//播放

- (void)playAudio:(NSString *)path {

? ? NSURL *url = [NSURL URLWithString:path];

? ? NSError *err = nil;

? ? audioPalyer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&err];

? ? audioPalyer.delegate = self;

? ? [audioPalyer prepareToPlay];

? ? [audioPalyer play];

}



//停止播放

- (void)stopAudio {

? ? if (audioPalyer) {

? ? ? ? [audioPalyer stop];

? ? ? ? audioPalyer = nil;

? ? }


}

- (void)playing

{

? ? if([audioPalyer isPlaying])

? ? {

? ? ? ? [audioPalyer pause];

? ? }

?? ?

? ? else

? ? {

? ? ? ? [audioPalyer play];

? ? }


}

#pragma mark -AVAudio 代理方法-

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag

{

?

}


OK ?問題解決

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/458697.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/458697.shtml
英文地址,請注明出處:http://en.pswp.cn/news/458697.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

iOS開發網絡篇—Reachability檢測網絡狀態

前言&#xff1a;當應用程序需要訪問網絡的時候&#xff0c;它首先應該檢查設備的網絡狀態&#xff0c;確認設備的網絡環境及連接情況&#xff0c;并針對這些情況提醒用戶做出相應的處理。最好能監聽設備的網絡狀態的改變&#xff0c;當設備網絡狀態連接、斷開時&#xff0c;程…

網絡七層協議 五層模型 TCP連接 HTTP連接 socket套接字

socket&#xff08;套接字&#xff09;是通信的基石&#xff0c;是支持TCP/IP協議的網絡通信的基本操作單元&#xff0c;包含進行網絡通信必須的五種信息&#xff1a;連接使用的協議&#xff0c;本地主機的IP地址&#xff0c;本地進程的協議端口&#xff0c;遠地主機的IP地址&a…

[vs2010 project] CppUnit快速入門

簡介 測試是軟件開發過程中極其重要的一環&#xff0c;詳盡周密的測試能夠減少軟件BUG&#xff0c;提高軟件品質。測試包括單元測試、系統測試等。其中單元測試是指針對軟件功能單元所作的測試&#xff0c;這里的功能單元可以是一個類的屬性或者方法&#xff0c;測試的目的是看…

[javascript|基本概念|Number]學習筆記

Number類型的值&#xff1a;整數/浮點數值 整數 十進制 e.g.: var intNum 50; 八進制 (嚴格模式下無效,解析錯誤)字面值首位必須是0,之后的數字序列為0&#xff5e;7 e.g.: var intNum 070; //解析為十進制56 (如果字面值數值超出了范圍&#xff0c;前導0將被忽略&#xf…

[轉]深入理解linux內核list_head

http://blog.chinaunix.net/uid-27122224-id-3277511.html 深入理解linux內核list_head的實現 2012-07-17 17:37:01 分類&#xff1a; LINUX 前言&#xff1a;在linux源代碼中有個頭文件為list.h。很多linux下的源代碼都會使用這個頭文件&#xff0c;它里面定義 了一個結構,以及…

xcode左側不顯示工程文件目錄,提示NO Filter Results

解決辦法&#xff1a; What solved was to go to Navigate > Reveal in Project Navigator . After this, the structure appeared again.

【VC++技術雜談005】如何與程控儀器通過GPIB接口進行通信

在工控測試系統中&#xff0c;經常需要使用到各類程控儀器&#xff0c;這些程控儀器通常具有GPIB、LAN、USB等硬件接口&#xff0c;計算機通過這些接口能夠與其通信&#xff0c;從而實現自動測量、數據采集、數據分析和數據處理等操作。本文主要介紹如何與程控儀器通過GPIB接口…

標題在上邊框中的html(fieldset標簽)

<fieldset> <legend>標題</legend> 內容 </fieldset> 轉載于:https://www.cnblogs.com/lswbk/p/4952820.html

移除項目中的CocoaPods

在項目中移除CocoaPods cocoaPods雖然很方便&#xff0c;但是我是真心的不喜歡用它&#xff0c;總是出錯如果你覺得CocoaPods讓你的項目出現了問題&#xff0c;不好用甚至是惡心&#xff0c;想將其從項目中徹底移除&#xff0c;也有方法&#xff1a; 1.刪除工程文件夾下的Podf…

ShellExecute使用詳解

有三個API函數可以運行可執行文件WinExec、ShellExecute和CreateProcess。 1.CreateProcess因為使用復雜&#xff0c;比較少用。 2.WinExec主要運行EXE文件。如&#xff1a;WinExec(Notepad.exe Readme.txt, SW_SHOW); 3.ShellExecute不僅可以運行EXE文件&#xff0c;也可以運行…

javascript筆記整理(對象基礎)

一、名詞解釋 1.基于對象&#xff08;一切皆對象&#xff0c;以對象的概念來編程&#xff09; 2.面向對象編程(Object Oriented Programming&#xff0c;OOP) A.對象(JavaScript 中的所有事物都是對象) B.對象的屬性和行為 屬性:用數據值來描述他的狀態 行為:用來改變對象行為的…

java的安裝和配置

JRE (JAVA Runtime Enviroment java運行環境),包括JVM(java虛擬機)和java程序所需的核心功能類庫&#xff0c;如果只是運行java程序&#xff0c;只需安裝JRE。 JDK &#xff08;Java Development Kit 開發工具包&#xff09;包括開發JAVA程序時所需的工具&#xff0c;包括JRE…

#if, #ifdef, #ifndef, #else, #elif, #endif的用法

#ifdef的用法 靈活使用#ifdef指示符&#xff0c;我們可以區隔一些與特定頭文件、程序庫和其他文件版本有關的代碼。 代碼舉例&#xff1a;新建define.cpp文件 &#xff03;include "iostream.h" int main() { #ifdef DEBUG cout<< "Beginning ex…

redhat 6.6 安裝 (LVM)

http://www.cnblogs.com/kerrycode/p/4341960.html轉載于:https://www.cnblogs.com/zengkefu/p/4954955.html

MFC對話框最小化到托盤

1、在資源中的Icon中導入一個自己喜歡的圖標&#xff0c;ID命名為IDR_MAINFRAME&#xff0c;將先前的IDR_MAINFRAME的圖標刪除掉&#xff1b; 2、在自己的Dialog頭文件中定義一個變量 NOTIFYICONDATA m_nid&#xff0c;關于該結構體的具體信息可以查閱MSDN&#xff1b; 3、添加…

Android acache讀后感

今天了解到了一個android輕量級的開源緩存框架,(github&#xff1a;https://github.com/yangfuhai/ASimpleCache),花了一點時間研究了一下源代碼&#xff0c;大概的思路就是每個緩存目錄對應一個Acache類&#xff0c;通過mInstanceMap關聯&#xff08;個人覺得這個主要是減少對…

continue break

塊作用域 一個塊或復合語句是用一對花括號&#xff08;"{}"&#xff09;括起來的任意數量的簡單的java語句。塊定義了變量的作用范圍。 1、嵌套塊是方法內的嵌套&#xff0c;不包括類的花括號。在嵌套塊內的 變量是不可以重復定義的。 2、不允許重復定義的是局部變…

GetVersionEx 獲取系統版本信息

轉自&#xff1a;http://blog.csdn.net/yyingwei/article/details/8286658 最近在windows 8上獲取系統版本信息需要調用系統API&#xff0c;于是用到了GetVersionEx。 首先看一看函數原型&#xff1a; [cpp] view plaincopy BOOL GetVersionEx(POSVERSIONINFO pVersionInformat…

popoverController(iPad)

一、設置尺寸 提示&#xff1a;不建議&#xff0c;像下面這樣吧popover的寬度和高度寫死。 1 //1.新建一個內容控制器2 YYMenuViewController *menuVc[[YYMenuViewController alloc]init];3 4 //2.新建一個popoverController&#xff0c;并設置其內容控制器5 s…

靜態成員變量和非靜態成員變量的對比

靜態成員變量和非靜態成員變量的對比 1、存儲的數據 靜態成員變量存儲的是所有對象共享的數據 非靜態成員變量存儲的是每個對象特有的數據 2、存儲位置 靜態成員變量是隨著類的加載在方法區的靜態區開辟內存了 非靜態成員變量是隨著對象的創建再堆中開辟內存 3、調用方式 靜態成…