使用dispatch_async NSURLSession调用的结果更新UILabel

时间:2014-01-05 19:19:50

标签: ios objective-c ios7 uilabel nsurlsession

几周前我开始使用Objective-C编程,所以我理解了所有这些部分是如何组合在一起的。他们所发生的命令仍然让我感到困惑。我正在尝试使用NSURLSession对我的某个应用程序进行JSON API调用。这一切都完美无瑕,但我想用一条返回的数据更新标签&无论何时我查看/尝试更新标签,我都会为空。

我发现的一些与我的问题类似的帖子包括:thisthisthisthis。来自Ruby on Rails的世界,我根本不需要处理异步概念,但我知道我很接近。

以下是相关代码片段:

        if (!jsonError) {
            NSDictionary *skillBuildData = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];

            dispatch_async(dispatch_get_main_queue(), ^{
                    NSLog(@"%@:", skillBuildNameLabel.text);  // should say "Build Name" but returns null
                    NSLog(@"%@", skillBuildData[@"name"]);    // correctly prints the result
                    NSLog(@"%@:", skillBuildNameLabel.text);  // should have contents of skillBuildData[@"name"] but returns null
                    skillBuildNameLabel.text = skillBuildData[@"name"]; // obviously results in null, but I don't know why.
            });
        }

修改

不确定它是否相关,但这是我ViewController.h的大部分内容,可以让您了解这些网点和内容。这个非常简单的应用中的动作。一键,一种方法,IBOutlet链接按钮& JSON调用方法和标签:

@interface ViewController : UIViewController {
    IBOutlet UILabel *skillBuildNameLabel;
    IBOutlet UIButton *getSkillBuildDataButton;
}

- (void)getSkillBuildDataById:(int) skillBuildId;

- (IBAction)buttonPressed;

好像我很亲密,我只是看不到我错过的链接。非常感谢你!

编辑2:

查看Ben Kreeger对我标记为答案的回复的评论。我没有将故事板中的实际标签连接到我在ViewController.h中创建的插座。我不知道你可以将一行从故事板中的元素拖到实际的代码行。那是缺失的一块。看起来我还有很多东西可以学习Xcode& Objective-C的。感谢所有帮助过我的人!

2 个答案:

答案 0 :(得分:2)

您可能有更多运气声明将IBOutlets作为属性(@property)而非实例变量(请参阅this answer了解原因weak而不是strong )。

@interface ViewController : UIViewController

@property (weak, nonatomic) IBOutlet UILabel *skillBuildNameLabel;
@property (weak, nonatomic) IBOutlet UIButton *getSkillBuildDataButton;

...

@end

然后,您就可以在实施中将其引用为self.skillBuildNameLabelself.getSkillBuildDataButton

请注意,像这样的回调中的self.x符号可能会导致所谓的保留周期。如果是这种情况,Xcode会警告你。 Here's a bit on retain cycles for you

脚注:我很少再看到(并且永远不会写)这种语法来声明实例变量。

@interface ViewController : UIViewController {
    IBOutlet UILabel *skillBuildNameLabel;
    IBOutlet UIButton *getSkillBuildDataButton;
}

改为使用属性。

答案 1 :(得分:1)

您在设置文本之前正在进行日志记录。移动

skillBuildNameLabel.text = skillBuildData[@"name"];

到异步块的顶部,在NSLog语句之上。