我是dispatch_queue_t
的新用户,我的应用程序存在两个问题,我认为可以使用GCD解决。第一个是在主视图(ViewController)中我有一个标签,由另一个类(AudioViewController)实现,当我在ViewController中进行任何用户交互时,标签停止实现,所以我想如果我使用{{1这个问题将得到解决。
第二件事是在同一主视图(ViewController)中,当我按下一个贡献时,我调用另一个类(ContributionViewController),这个类只访问另一个类的实例变量(AudioViewController),它一直刷新。当我开始贡献时,我做了一个循环以获得多个值来与它们进行一些微积分,但这些值都是相同的。
我会在这里放一些代码来试图清除这些东西。
dispatch_queue_t
ViewController.m
- (IBAction)makeContribution:(id)sender
{
NSLog(@"A: Contribution button clicked");
NSLog(@"-= START CONTRIBUTION =-");
cvc = [[ContributionViewController alloc] init];
cvc.avc = self.avc;
// Get NUM_CONTRIBUTIONS contributions to make average.
int contContribution;
for (contContribution = 0; contContribution < NUM_CONTRIBUTIONS; contContribution++) {
[cvc getEachContribution];
}
// Make average
[cvc makeAverage:NUM_CONTRIBUTIONS];
[cvc release];
}
AudioViewController.m
- (void)audioInitializationWithTimeInterval:(float)time
{
NSDictionary* recorderSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kAudioFormatLinearPCM],AVFormatIDKey,
[NSNumber numberWithInt:44100],AVSampleRateKey,
[NSNumber numberWithInt:1],AVNumberOfChannelsKey,
[NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,
[NSNumber numberWithBool:NO],AVLinearPCMIsBigEndianKey,
[NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,
nil];
NSError* error;
NSURL *url = [NSURL fileURLWithPath:@"/dev/null"];
recorder = [[AVAudioRecorder alloc] initWithURL:url settings:recorderSettings error:&error];
//enable measuring
//tell the recorder to start recording:
[recorder record];
if (recorder) {
[recorder prepareToRecord];
recorder.meteringEnabled = YES;
[recorder record];
levelTimer = [NSTimer scheduledTimerWithTimeInterval:time target:self selector:@selector(levelTimerCallback:) userInfo:nil repeats:YES];
}
else
NSLog(@"%@",[error description]);
}
- (void)levelTimerCallback:(NSTimer *)timer
{
//NSLog(@"-= AVC =-");
[recorder updateMeters];
db = [recorder averagePowerForChannel:0] - DBOFFSET;
db += 120;
db = db < 0 ? 0 : db;
vc.lab_decibel.text = [NSString stringWithFormat:@"%0.0f", db];
}
ContributionViewController.m
所以,主要的是- (void)getEachContribution
{
actualContribution = self.avc.db;
NSLog(@"Actual contribution: %f", actualContribution);
NSLog(@"Sum before: %0.2f", sumContribution);
sumContribution += actualContribution;
NSLog(@"Sum After: %0.2f", sumContribution);
}
- (void)makeAverage:(int)numOfContributions
{
self.average = self.sumContribution / numOfContributions;
NSLog(@"Average: %0.2f", self.average);
}
将解决我的问题以及如何做到这一点?我试图将dispatch_queue_t
放在AudioViewController,ContributionViewController和ViewController上,但是第一个没有更新标签,第二个没有崩溃,第三个标签仍然是0值。
感谢您解决此问题的任何提示。
编辑01:
分贝标签一直在变化。
答案 0 :(得分:0)
好的,这开始有意义了。我不懂mapView,贡献等语言。这完全是神秘的,但我想我已经开始理解你的问题了。据我了解,您的问题是您的用户界面未更新的原因。好的,你的问题的最大答案是,如果你不想,你不需要GCD。 NSTimer
可以满足您的需求。
现在,您说不再更新您不断更新的数据库字段。绝对没有理由不继续这样做。我试过了,它运行正常。那里有些事情发生了。就个人而言,当我有一个正在更新我的用户界面的NSTimer时,我确保在viewDidDisappear
中将其关闭(如果不可见,则无需更新您的用户界面)并始终在{{1}中启用它}。当我这样做时,每当我使用db编号返回主视图时,它就会愉快地恢复。或者如果我想要另一个视图控制器来获取通知,我只是使用委托将其重新打开。
这可能如下所示。
首先,您可能需要委托协议:
viewDidAppear
然后,您想要定义DecibelNotifier类:
// DecibelNotifierDelegate.h
#import <Foundation/Foundation.h>
@protocol DecibelNotifierDelegate <NSObject>
@required
- (void)decibelNotifierUpdate:(CGFloat)db;
@end
和
// DecibelNotifier.h
#import <Foundation/Foundation.h>
#import "DecibelNotifierDelegate.h"
@interface DecibelNotifier : NSObject
@property (nonatomic, retain) id<DecibelNotifierDelegate> delegate;
@property CGFloat db;
- (void)startWithInterval:(float)time target:(id<DecibelNotifierDelegate>)delegate;
- (void)stop;
@end
因此,第一个想要通知的视图控制器可能具有属性:
// DecibelNotifier.m
#import "DecibelNotifier.h"
#import "AVFoundation/AVFoundation.h"
@interface DecibelNotifier ()
{
AVAudioRecorder *_recorder;
NSTimer *_levelTimer;
}
@end
// note, your code makes reference to DBOFFSET and I don't know what that is. Update this following line accordingly.
#define DBOFFSET 0
@implementation DecibelNotifier
@synthesize delegate = _delegate;
@synthesize db = _db;
- (id)init
{
self = [super init];
if (self)
{
NSDictionary* recorderSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kAudioFormatLinearPCM],AVFormatIDKey,
[NSNumber numberWithInt:44100],AVSampleRateKey,
[NSNumber numberWithInt:1],AVNumberOfChannelsKey,
[NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,
[NSNumber numberWithBool:NO],AVLinearPCMIsBigEndianKey,
[NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,
nil];
NSError* error;
NSURL *url = [NSURL fileURLWithPath:@"/dev/null"];
_recorder = [[AVAudioRecorder alloc] initWithURL:url settings:recorderSettings error:&error];
if (!_recorder)
NSLog(@"%@",[error description]);
}
return self;
}
- (void)startWithInterval:(float)time target:(id<DecibelNotifierDelegate>)delegate
{
if (_recorder)
{
self.delegate = delegate;
[_recorder prepareToRecord];
_recorder.meteringEnabled = YES;
[_recorder record];
_levelTimer = [NSTimer scheduledTimerWithTimeInterval:time target:self selector:@selector(levelTimerCallback:) userInfo:nil repeats:YES];
}
}
- (void)stop
{
[_recorder stop];
[_levelTimer invalidate];
_levelTimer = nil;
self.delegate = nil;
}
- (void)levelTimerCallback:(NSTimer *)timer
{
[_recorder updateMeters];
CGFloat db = [_recorder averagePowerForChannel:0] - DBOFFSET;
db += 120;
db = db < 0 ? 0 : db;
_db = db;
[self.delegate decibelNotifierUpdate:db];
}
@end
您可以使用以下命令对其进行初始化:
@property (strong, nonatomic) DecibelNotifier *dBNotifier;
然后,您可以使用以下命令启用通知
self.dBNotifier = [[DecibelNotifier alloc] init];
所以问题是当你打开和关闭这些通知时。我在[self.dBNotifier startWithInterval:0.25 target:self];
和viewWillAppear
中执行此操作。您也可以将dbNotifier传递给其他视图控制器,它们也可以收到通知。
就像我说的那样,我尝试了这个并且它工作正常,任何想要获得通知的视图控制器都可以打开它并将自己指定为委托,并且你将参加比赛。