ios/objective c/singleton: Storing userid in sessi

2020-05-09 23:14发布

问题:

I defined an NSInteger in a singleton (for userid) and access it in another class. However, while I have managed to get rid of error messages so it builds, the app crashes when it hits line.

Here is the initial definition;

Session.h

@interface Session : NSObject
@property (assign,nonatomic) NSInteger *userid;
+ (IDSession *)sharedInstance;

Session.m

@implementation Session
+ (Session *)sharedInstance {
    static Session *session;
    if (!session){
        session = [[Session alloc] init];
        NSInteger *userid=1;
        //include this class in other class and reference userid with [Session sharedInstance].userid
    }
    return session;
}

Attempt to get session in other class that imports above class

in save method:

 NSInteger *number =[Session sharedInstance].userid;//crashes here log says (lldb)

Would appreciate any suggestions on how to fix this.

Thank you.

回答1:

Firstly, I recommend you follow this idiom for creating a thread safe singleton.

+ (Singleton *)sharedSettings{

    static Singleton *singleton;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        singleton = [[self alloc] initPrivate];

    });

    return singleton;

}

- (instancetype)initPrivate{

    self = [super init];
    if(!self) return nil;


    return self;

}

Also, NSInteger is not an object. It is a typedef for a primitive long. So remove the object pointer.

typedef long NSInteger;

You seem to be confusing NSInteger with the NSNumber wrapper. Take a look at the docs for NSNumber.



回答2:

Here is my standart session object

H file

@interface ControllerSession : NSObject
@property(nonatomic, strong) NSString* sID;
@property(nonatomic, strong) NSDate* sDate;

#pragma mark sharedInstance
+ (ControllerSession*)sharedInstance;

#pragma mark sessionVariables
- (void)sessionVariableAddWithName:(NSString*)name WithValue:(id)value;
- (id)sessionVariableGetWithName:(NSString*)name;

@end

M file

//
//  ControllerSession.m
//  FitTechs
//
//  Created by Add080bbA on 19/04/16.
//  Copyright © 2016 Dayamatron. All rights reserved.
//
#import "ControllerModel.h"
#import "ControllerSession.h"
#import "ControllerSystem.h"

//#import "includeListCategories.h"
#import "NSObject+AppDelegate.h"

@interface ControllerSession ()
@property(nonatomic, strong) ControllerSystem* ctrlSystem;
@property(nonatomic, strong) ControllerModel* ctrlModel;
@property(nonatomic, strong) Session* sessionEntity;
//+ (NSMutableDictionary*)sessionVariables;
@end

@implementation ControllerSession

@synthesize ctrlSystem;
@synthesize ctrlModel;
@synthesize sessionEntity;

@synthesize sID;
@synthesize sDate;

#pragma mark sharedInstance
static ControllerSession* objSelf;
+ (ControllerSession*)sharedInstance {
  if (!objSelf) {
    static dispatch_once_t onceTokenControllerSession;
    dispatch_once(&onceTokenControllerSession, ^{
      objSelf = [[ControllerSession alloc] init];
    });
  }
  return objSelf;
}

#pragma mark init
- (id)init {
  self = [super init];
  if (self) {
    ctrlModel = self.appdel.ctrlModel;
    ctrlSystem = self.appdel.ctrlSystem;

    // session CoreData Stuff to record permanently
    sessionEntity = [ctrlModel sessionCreateBlank];
    sessionEntity.systemOSVersion =
        [NSNumber numberWithFloat:ctrlSystem.osVersion];
    sessionEntity.systemLocale = ctrlSystem.localeCurrent;
    sessionEntity.systemHardware = ctrlSystem.hardware;
    sessionEntity.systemLanguagesPrefered =
        [ctrlSystem languagesPreferedCombinedWithString:@";"];
    sessionEntity.systemLanguageSelected = ctrlSystem.languageSelected;

    [ctrlModel saveContext];
  }
  return self;
}

#pragma mark sessionVariables
// session Temp Stuff to record
static NSMutableDictionary* sessionDict;
// singleton session dict object
- (NSMutableDictionary*)sessionDictGet {
  if (!sessionDict) {
    static dispatch_once_t onceTokensessionDictGet;
    dispatch_once(&onceTokensessionDictGet, ^{
      sessionDict = [[NSMutableDictionary alloc] init];
    });
  }
  return sessionDict;
}

- (void)sessionVariableAddWithName:(NSString*)name WithValue:(id)value {
  [self.sessionDictGet setObject:value forKey:name];
}
- (id)sessionVariableGetWithName:(NSString*)name {
  return [self.sessionDictGet objectForKey:name];
}

@end


回答3:

The following code using NSString instead of numbers and setting a local variable rather than a property works:

Session.h
@interface IDSession : NSObject
@property (readonly, copy) NSString *userid;
+ (IDSession *)sharedInstance;  
@end

Session.m
#import "IDSession.h"
@interface IDSession()
@property (readwrite,copy)NSString * userid;

@end

@implementation IDSession

+ (IDSession *)sharedInstance {
    static IDSession *session;
    if (!session){
        session = [[IDSession alloc] init];
        //include this class in other class and reference userid with [IDSession sharedInstance].userid
        NSString * userid = @"1";
    }
    return session;
}
@end
in retrieving class.

#import "session.h"

   NSString *userid =[Session sharedInstance].userid;
    NSLog(@"userid retrieved from session variable is %@",userid);