Ios 单例未在ViewController/spritekit场景中持久化

Ios 单例未在ViewController/spritekit场景中持久化,ios,singleton,sprite-kit,Ios,Singleton,Sprite Kit,这是一款SpriteKit游戏 我使用单例来存储单个“Show”对象,以便在整个游戏中访问。“Show”类具有NSString属性“showTitle” 在ViewController1中,我设置了singleton的'Show'属性。检验。。然后,我从singleton打印出一个字符串属性'Show'(showtTitle),它正确地打印字符串 在切换到ViewController2之后,我再次从singleton打印出相同的字符串属性'Show'(showTitle),它再次正确打印字符串

这是一款SpriteKit游戏

我使用单例来存储单个“Show”对象,以便在整个游戏中访问。“Show”类具有NSString属性“showTitle”

在ViewController1中,我设置了singleton的'Show'属性。检验。。然后,我从singleton打印出一个字符串属性'Show'(showtTitle),它正确地打印字符串

在切换到ViewController2之后,我再次从singleton打印出相同的字符串属性'Show'(showTitle),它再次正确打印字符串

然后,从ViewController2初始化spritekit场景。我尝试打印相同的字符串属性 来自单例的'Show',并打印null而不是字符串。我走得更远,转到ViewController3,试图从singleton打印showTitle。。。。。空

为什么我可以在ViewController1和2中访问singleton的“Show”属性,但不能从sprite工具包场景或ViewController3中访问。我哪里做错了

ShowSingleton.h

#import <Foundation/Foundation.h>
#import "Show.h"

@interface ShowSingleton : NSObject

@property (nonatomic, strong) Show* currentShow;

+(ShowSingleton *)singleton;

@end
ViewController1:

- (IBAction)openShow:(UIButton*)sender
    {
        //showsarray is an array of 'Show' objects retrieved through core data in another class
        [ShowSingleton singleton].currentShow = [showsarray objectAtIndex:sender.tag];

        NSLog(@"Opened show: %@", [ShowSingleton singleton].currentShow.showTitle);
        //The above line correctly prints the selected showTitle from the singleton
}
openShow:完成后,一个序列将打开ViewController2。ViewController2初始化SpriteKit场景

ViewController2:

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    SKView * skView = (SKView *)self.view;
    if (!skView.scene)
    {
        skView.showsFPS = YES;
        skView.showsNodeCount = YES;
        SKScene * scene = [iMarchMyScene sceneWithSize:skView.bounds.size];
        scene.scaleMode = SKSceneScaleModeAspectFill;
        [skView presentScene:scene];
    }
}

- (void)viewDidLoad
{
    //The following line correctly prints the showTitle from ViewController2
    NSLog(@"processing show: %@", [ShowSingleton singleton].currentShow.showTitle);
}
myScene.m:

-(id)initWithSize:(CGSize)size
{
    if (self = [super initWithSize:size])
    {
        if ([ShowSingleton singleton].currentShow)
        {
            //This always gets called, which tells me the object exists, but null is printed for showTitle
             NSLog(@"show title from scene: %@", [ShowSingleton singleton].currentShow.showTitle);
        }
    }
    return self;
}

ShowSingleton*shared
的作用域是方法,而不是类

尝试将其声明为AppDelegate的类属性,然后使用如下内容重写getter:

@property (strong, nonatomic) Show *currentShow;
然后将getter重写为:

+(Show*)currentShow
{
    static id _currentShow = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        currentShow = [showsarray objectAtIndex:sender.tag]; //probably not this, not sure where in your app flow this info is ready...
    });
    return _currentShow;
}
现在,您可以利用Apple提供的适当的单例UIApplicationLegate,并最终获得一个不变的
Show
实例,通过调用
(YourApplicationClass*)[[UIApplication sharedApplication]currentShow]

请记住,dispatch_once与应用程序生命周期息息相关。当且仅当应用程序终止时(可能是在应用程序处于后台时),它将被清除

Singleton的实现非常灵活,而且更难知道它们的使用何时真正得到了保证,因此您可能需要查看
NSUserDefaults
,看看它是否有一些适合您的用途的东西

考虑使用单例实现:

// ShowSingleton.h

#import <Foundation/Foundation.h>
#import "Show.h"

@interface ShowSingleton : NSObject

+ (instancetype)singleton;

@end

// ShowSingleton.m

#import "ShowSingleton.h"

@implementation ShowSingleton

+ (instancetype)singleton {
   static id sharedInstance = nil;

   static dispatch_once_t onceToken;
   dispatch_once(&onceToken, ^{
      sharedInstance = [[self alloc] init];
   });

   return sharedInstance;
}

@end
//ShowSingleton.h
#进口
#导入“Show.h”
@接口ShowSingleton:NSObject
+(instancetype)单例;
@结束
//ShowSingleton.m
#导入“ShowSingleton.h”
@单例实现
+(instancetype)单例{
静态id sharedInstance=nil;
静态调度一次;
一次发送(一次发送)^{
sharedInstance=[[self alloc]init];
});
返回共享状态;
}
@结束

如果你必须使用自己的singleton(我真的要先对这个前提提出一些怀疑),那么Andrey是对的,为了引导你,他向你展示了如何使用instancetype而不是id,在这种情况下,这绝对是美好的,原因不符合我评论中的角色限制……我知道单身通常是不可以的。这是我想到的第一件事。你们有谁对我的工作有更好的建议吗?”“显示”是一个CoreData对象。一旦用户从列表中选择其对象,其他视图控制器和场景将基于该CoreData对象更新UI、变量等。我认为单例是存储对象以供全局使用的好地方。有什么更好的方法?请记住,任何视图控制器都可以对对象进行更改并将其保留在存储中。managedObjectContext位于appDelegate中。
// ShowSingleton.h

#import <Foundation/Foundation.h>
#import "Show.h"

@interface ShowSingleton : NSObject

+ (instancetype)singleton;

@end

// ShowSingleton.m

#import "ShowSingleton.h"

@implementation ShowSingleton

+ (instancetype)singleton {
   static id sharedInstance = nil;

   static dispatch_once_t onceToken;
   dispatch_once(&onceToken, ^{
      sharedInstance = [[self alloc] init];
   });

   return sharedInstance;
}

@end