Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/97.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 将数据块中的数据保存到NSMutableDictionary中,以及通常的块_Ios_Objective C_Objective C Blocks - Fatal编程技术网

Ios 将数据块中的数据保存到NSMutableDictionary中,以及通常的块

Ios 将数据块中的数据保存到NSMutableDictionary中,以及通常的块,ios,objective-c,objective-c-blocks,Ios,Objective C,Objective C Blocks,我很难找到使用积木的最佳方法。我正在尝试检索计步器数据,访问数据的方法是块 [self.pedometer queryPedometerDataFromDate:yesterday toDate:midnightOfToday withHandler:^(CMPedometerData *pedometerData, NSError *error)

我很难找到使用积木的最佳方法。我正在尝试检索计步器数据,访问数据的方法是块

[self.pedometer queryPedometerDataFromDate:yesterday
                                        toDate:midnightOfToday
                                   withHandler:^(CMPedometerData *pedometerData, NSError *error) {

         dispatch_async(dispatch_get_main_queue(), ^{
             if (error) {
                 NSLog(@"Pedometer is NOT available.");
             }
             else {
                 NSLog(@"Steps %@", pedometerData.numberOfSteps);
                 yesterdaysNumbersLabel.text = [pedometerData.numberOfSteps stringValue];
                 [pedometerDictionary setValue:[pedometerData.numberOfSteps stringValue] forKey:@"2"];
             }
         });
     }];
使用上面的代码,我可以获取数据、记录数据并更新屏幕上的标签,但我不知道如何将数据设置到数组或字典中,以便我可以对其执行其他操作

我明白为什么数组和字典总是空的。。。这些块在不同的线程上运行,我在这些块完成之前访问它们

有人能帮我弄清楚如何利用这些数据做更多的事情吗

更新1:

现在我把这个放进了h

@property (strong, atomic) NSMutableDictionary *pedometerDictionary;
我把它合成在.m中,我称之为

[self getNumbersForYesterday];
NSLog(@"Dictionary: %@", pedometerDictionary);
…它运行上述函数并立即尝试记录结果。正如我所说,我理解它不起作用的所有原因。我只需要想办法改变我正在做的事情,让它工作起来

更新2:

这是in.h

@property (strong, atomic) NSMutableDictionary *pedometerDictionary;
这是我的

@synthesize pedometerDictionary;

- (id)init {
    self = [super init];
    if (self != nil) {
        self.pedometerDictionary = [[NSMutableDictionary alloc] init];
    }
    return self;
}
我就是这样用的

[self getNumbersForYesterday];
NSLog(@"Dictionary: %@", self.pedometerDictionary);
叫这个

- (void)getNumbersForYesterday {

    [self.pedometer queryPedometerDataFromDate:yesterday
                                        toDate:midnightOfToday
                                   withHandler:^(CMPedometerData *pedometerData, NSError *error) {

         dispatch_async(dispatch_get_main_queue(), ^{
             if (error) {
                 NSLog(@"Pedometer is NOT available.");
             }
             else {
                 NSLog(@"Steps %@", pedometerData.numberOfSteps);
                 yesterdaysNumbersLabel.text = [pedometerData.numberOfSteps stringValue];
                 [self.pedometerDictionary setValue:[pedometerData.numberOfSteps stringValue] forKey:@"2"];

             }

         });
     }];

}

如果我只想把所有的工作都留在街区里,我会没事的。我所理解的是,由于块是异步的,所以我正在尝试NSLog我的字典,而块还没有完成运行。因此,我的字典仍然是空的。

美元到甜甜圈,你的
pedometerDictionary
从一开始就没有创建过(或者是创建过,但声明没有用)

也就是说,你的代码行在哪里,上面写着
pedometerDictionary=[[NSMutableDictionary alloc]init]?而
pedometerDictionary
在哪里声明?您是如何尝试从中提取
NSLog()
值的

另外,使用
setObject:forKey:



同样奇怪的是,它被命名为
pedometerDictionary
。这表明它要么声明为全局变量(不应该是全局变量),要么声明为包含上述代码的任何方法的局部变量(不起作用),要么直接声明并使用实例变量。

您遇到的问题不是块计时问题,你的字典永远不应该是nil,最坏的情况是它不会包含任何值

在使用词典之前,您需要先创建词典。对于大多数对象,合适的位置应该是
init
方法。如果要在Interface Builder中创建对象,则方法应为
awakeFromNib

要使用字典,您可以使用NSTimer或从QueryPDometerDataFromDate块处理程序调用方法。使用
@synchronized()
指令就是一个示例,说明了如何在线程化环境中同时避免对字典的访问重叠。在这个特定的示例中,情况并非如此,因为您在主线程上进行调度,并且NSTimer也在主线程上运行。但是,如果您使用线程化的
@synchronized()
,将防止重复访问

@interface HelloWorld : NSObject
@property (retain, atomic) NSMutableDictionary *pedometerDictionary;
@property (retain, nonatomic) NSTimer *timer;
@end


@implementation HelloWorld
@synthesize pedometerDictionary, timer;


您正在寻找吗?除非您确实需要使用KVC,否则不要使用
setValue:forKey:
将对象添加到字典中。改用
setObject:forKey:
。你到底有什么问题?您发布的代码将对象添加到
pedometerDictionary
字典中。这里的问题是什么?问题是字典总是空的,因为我尝试访问它的每一种方式,甚至只是NSLog,当我尝试访问它时,块还没有完成。我想不出解决的办法。你确实分配了pedometerDictionary,对吗?我知道这是一个全新的切线,但为什么要提出
setObject:forKey
,并在一个不相关的问题上坚持它呢。这种差异几乎是无形的,许多人更喜欢
setValue:forKey:
,因为KVO能够接受一个nil值。@Conor为什么要提出它?改进OP的代码。KVC方法通常应限于针对具体模型层对象使用。字典不接受setter上的nil(并且只接受对象)的约定不应该仅仅为了方便而被KVC绕过。在这条道路上,存在着维护方面的难题;使用正确定义的模型层会更好。最糟糕的攻击是在NS*集合类上混合使用KVC和非KVC;这导致了疯狂。谢谢你的详细说明。我将尝试更频繁地使用setObject。我多次被设置为nil(特别是在处理JSON数据时)所困扰,因此我发誓不再使用setObject。Bbum将按照@monolo的建议编写代码来验证文档的结构,这样我就不会依赖于潜在的随机意外值为nil。诚然,更多的代码行。但bbum的阵营是,预先在迂腐的错误检查中投入额外的代码行,比发现某个边缘服务器在某个地方吐出一个随机unicode字符的某个随机子集的客户更可取,因为该字符最不可能导致解析错误,导致“NULL是故障回退”中出现意外的NULL值图案我是那种老派(强调老的)人。:)Bbum是如此老派,他会使用那些预编译指令中的一个,la NSLog,将boiler pate代码封装在一行中。我太年轻了,无法理解变量参数宏,遗憾的是,我太老了,无法理解Swift中的选项@monolo如果你需要把Bbum从木制品中带出来,只需询问
retainCount
。嗨,Stephen,谢谢你添加更多信息。我认为您可能仍然缺少上面显示的
init
调用。也要确保总是给自己打电话。避免错误。正如bbum提到的,不要猜测需要什么代码来发布所有内容,我们可以更好地帮助您。谢谢您提供的额外代码。添加了
awakeFromNib
作为选项,而不是可能是问题的init
- (id)init {
    self = [super init];
    if (self != nil) {
        self.pedometerDictionary = [NSMutableDictionary dictionary];
        self.timer = [NSTimer timerWithTimeInterval:5.0 target:self selector:@selector(doSomethingInterestingWithDictionary:) userInfo:nil repeats:YES];
    }
    return self;
}
- (void)awakeFromNib {
    self.pedometerDictionary = [NSMutableDictionary dictionary];
    self.timer = [NSTimer timerWithTimeInterval:5.0 target:self selector:@selector(doSomethingInterestingWithDictionary:) userInfo:nil repeats:YES];
}
- (void)getNumbersForYesterday {
[self.pedometer queryPedometerDataFromDate:yesterday
                                    toDate:midnightOfToday
                               withHandler:^(CMPedometerData *pedometerData, NSError *error) {

     dispatch_async(dispatch_get_main_queue(), ^{
         if (error) {
             NSLog(@"Pedometer is NOT available.");
         }
         else {
             NSLog(@"Steps %@", pedometerData.numberOfSteps);
             yesterdaysNumbersLabel.text = [pedometerData.numberOfSteps stringValue];
             @synchronized (self) {
                 [self.pedometerDictionary setValue:[pedometerData.numberOfSteps stringValue] forKey:@"2"];
             }
             [self doSomethingInterestingWithDictionary:nil];
         }
     });
 }];
}


// Will be called when queryPedometerDataFromDate returns and from a timer every 5 seconds.
- (void)doSomethingInterestingWithDictionary:(NSTimer *)aTimer {
    @synchronized (self) {
        NSLog(@"My days dictionary: %@", self.pedometerDictionary);
    }
}