How to keep a variable in memory until the app quits - ios

I have a singleton object in iOS that when instantiated parses a CSV file and then holds the results. I would like to make this object universally accessible and I would like it to not be released from memory until the app quits. I am running ARC so I cannot do manual retains.
Is there a way I can do this so it will work with ARC?
Header File:
#import <Foundation/Foundation.h>
#import "CHCSV.h"
#import "RCParserObject.h"
#interface ParserStore : NSObject <CHCSVParserDelegate>
{
// CSV Variables
RCParserObject *item;
NSMutableArray *data;
NSMutableArray *parsedData;
int fields;
bool open;
}
#property (atomic, retain) RCParserObject *item;
#property (atomic, retain) NSMutableArray *data;
#property (atomic, retain) NSMutableArray *parsedData;
#property (atomic) int fields;
#property (atomic) bool open;
+ (ParserStore *) defaultStore;
- (void) parseCSVFile:(NSString*)file;
- (void) categorizeData;
Implementation File
#import "ParserStore.h"
#import "RCParserObject.h"
#import "RCDetailItem.h"
static ParserStore *defaultStore;
#implementation ParserStore
#synthesize item, data, parsedData, fields, open;
# pragma mark -
# pragma mark Singleton Methods
+ (ParserStore *) defaultStore
{
if (!defaultStore)
{
defaultStore = [[super allocWithZone:NULL] init];
}
return defaultStore;
}
+ (id) allocWithZone:(NSZone *)zone
{
return [self defaultStore];
}
- (id) init
{
NSLog(#"Running init on parser store");
if (defaultStore)
{
NSLog(#"Self data count is %d, right before return", self.parsedData.count);
return defaultStore;
}
// NSLog(#"This better only happen once");
self = [super init];
[self setParsedData:[[NSMutableArray alloc] init]];
[self parseCSVFile:#"ContentNoPathFileExt2ASCII"];
[self categorizeData];
// NSLog(#"Self data count is %d when first created", self.parsedData.count);
return self;
}
#property (atomic, retain) RCParserObject *item;
#property (atomic, retain) NSMutableArray *data;
#property (atomic, retain) NSMutableArray *parsedData;
#property (atomic) int fields;
#property (atomic) bool open;
+ (ParserStore *) defaultStore;
- (void) parseCSVFile:(NSString*)file;
- (void) categorizeData;
#end

+(MySingleton *)singleton {
static dispatch_once_t pred;
static MySingleton *shared = nil;
dispatch_once(&pred, ^{
shared = [[MySingleton alloc] init];
shared.someVar = someValue; // if you want to initialize an ivar
});
return shared;
}
From anywhere:
NSLog(#"%#",[MySingleton singleton].someVar);
Note that your iOS app already has a singleton that you can access anywhere:
AppDelegate *delegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];

a simple singleton would be something like... in the .h:
#interface Foo : NSObject
+ (Foo *)sharedInstance;
#end
and in the .m:
static Foo *_foo = nil;
#implementation Foo
+ (Foo *)sharedInstance {
if (!_foo)
_foo = [[Foo alloc] init];
return _foo;
}
#end

Related

RLMResults:allObjects crash (iOS Objective-C)

I have old project written on Objective-C. Need to do migration to Realm.
I created several objects/classes inheritance from RLMObject. When I do fetching objects only with one main object type (ConnectionRealm) - working fine, but if I do add (only add, not include, not use) to project two or more another classes (inheritance from RLMObject), like as FloorRealm class, APP crash on [ConnectionRealm allObjects] without any errors.
Also ConnectionRealm contains RLMArray of FloorRealm. App still crashing.
(Can`t solve and understand this few days.) Thanks.
Connection Model:
#import <Foundation/Foundation.h>
#import <Realm/Realm.h>
#import "FloorRealm.h"
#interface ConnectionRealm : RLMObject
#property int connectionID;
#property NSString *name;
#property NSString *localIPAddress;
#property NSString *localPort;
#property NSString *remoteIPAddress;
#property NSString *remotePort;
#property NSString *userName;
#property NSString *password;
#property NSString *deviceID;
#property RLMArray <FloorRealm *> *floors;
- (instancetype)initWith:(NSString *)name
localIP:(NSString *)localIPAddress
localPort:(NSString *)lPort
remoteIP:(NSString *)remoteIPAddress
remotePort:(NSString *)rPort
userName:(NSString *)userName
password:(NSString *)password
deviceID:(NSString *)deviceID;
#end
#import "ConnectionRealm.h"
#implementation ConnectionRealm
- (instancetype)initWith:(NSString *)name
localIP:(NSString *)localIPAddress
localPort:(NSString *)lPort
remoteIP:(NSString *)remoteIPAddress
remotePort:(NSString *)rPort
userName:(NSString *)userName
password:(NSString *)password
deviceID:(NSString *)deviceID {
if (self = [super init]) {
self.connectionID = [self incrementID];
self.name = name;
self.localIPAddress = localIPAddress;
self.localPort = lPort;
self.remoteIPAddress = remoteIPAddress;
self.remotePort = rPort;
self.userName = userName;
self.password = password;
self.deviceID = deviceID;
}
return self;
}
+ (NSString *)primaryKey { return #"connectionID"; }
- (int)incrementID {
RLMResults *objects = [ConnectionRealm allObjects];
return self.connectionID = [[objects maxOfProperty:#"connectionID"] intValue] + 1;
}
#end
FloorModel:
#import <Realm/Realm.h>
#interface FloorRealm : RLMObject
#property int floorID;
#property NSInteger floorNumber;
#property NSString *floorName;
- (instancetype)initWith:(NSInteger)floorNumber floorName:(NSString *)name;
#end
RLM_ARRAY_TYPE(FloorRealm)
#import "FloorRealm.h"
#implementation FloorRealm
- (instancetype)initWith:(NSInteger)floorNumber floorName:(NSString *)name {
if (self = [super init]) {
self.floorID = [self incrementID];
self.floorNumber = floorNumber;
self.floorName = name;
}
return self;
}
+ (NSString *)primaryKey { return #"floorID"; }
- (int)incrementID {
RLMResults *objects = [FloorRealm allObjects];
return self.floorID = [[objects maxOfProperty:#"floorID"] intValue] + 1;
}
#end
[SOLVED]
RLM_ARRAY_TYPE(FloorRealm) need put on ConnectionRealm in .h after #includes. But in official docs written another.
Also: #property RLMArray <FloorRealm *><FloorRealm> *floors; instead of #property RLMArray <FloorRealm *> *floors;
I created test project with the same models and seed all errors. Strange, but in original project Xcode not showing this errors.

_OBJC_CLASS $_ClasConfig reference from

/*
#protocol ClasConfig
#end
*/
//class A
#interface ClassA : NSObject
#property (nonatomic) *companyA;
#property (nonatomic) NSArray *companyLists;
- (NSMutableArray*)getCompanyLists:(CompanyListModel *)productionListModel;
#end
//class config
#interface ClasConfig : NSObject
#property (nonatomic) NSString *Number;
#property (nonatomic) NSString *totalNumberOfCompany;
#end
#implementation ClassA
- (NSMutableArray*)getCompanyLists:(CompanyListModel *)productionListModel
{
ClasConfig *config = [[ClasConfig alloc] init]; **//Gives me linker error**
}
#end
ClasConfig *config = [[ClasConfig alloc] init]; //Gives me linker error
Though I have tried with importing protocol for reference.
For got to implement class of ClassConfig.
#implementation ClassConfig
#end
#implementation ClassA
- (NSMutableArray*)getCompanyLists:(CompanyListModel *)productionListModel
{
ClasConfig *config = [[ClasConfig alloc] init]; **//Gives me linker error**
}
#end

Class and class extension (category) in the same header file

When I look around the Cocoa Touch API, I can find some classes declared along with categories in the same header file, e.g.
#interface NSArray : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>
#property (readonly) NSUInteger count;
// and some other properties
#end
#interface NSArray (NSExtendedArray)
#property (readonly, copy) NSString *description;
// and some other properties
#end
Now I am trying to do the same thing with my class, like as follow:
#interface ARCTextbook : NSObject
#property (nonatomic) NSInteger ID;
#property (nonatomic) NSString *name;
#end
#interface ARCTextbook (Student)
#property (nonatomic) NSInteger studentID;
#property (nonatomic, getter=isUsed) BOOL used; // Used by a student?
#end
However, when I tried to access studentID or used property, I got an unrecognized selector error. Am I missing anything?
Cheers.
This is Associated Objects, you can refer documentation in below:
http://www.davidhamrick.com/2012/02/12/Adding-Properties-to-an-Objective-C-Category.html
How to store not id type variable use a objc_getAssociatedObject/objc_setAssociatedObject?
ARCTextbook.h
#import <Foundation/Foundation.h>
#interface ARCTextbook : NSObject
#property (nonatomic) NSInteger ID;
#property (nonatomic) NSString *name;
#end
#interface ARCTextbook (Student)
#property (nonatomic) NSInteger studentID;
#property (nonatomic, getter=isUsed) BOOL used; // Used by a student?
#end
ARCTextbook.m
#import "ARCTextbook.h"
#import <objc/runtime.h>
#implementation ARCTextbook
#end
static NSString *kStudentID = #"kStudentID";
static NSString *kUsed = #"kUsed";
#implementation ARCTextbook (Student)
#dynamic studentID;
#dynamic used;
- (void)setStudentID:(NSInteger)aStudentID {
objc_setAssociatedObject(self, (__bridge const void *)(kStudentID), #(aStudentID), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSInteger)studentID {
return [objc_getAssociatedObject(self, (__bridge const void *)(kStudentID)) integerValue];
}
- (void)setUsed:(BOOL)aUsed {
objc_setAssociatedObject(self, (__bridge const void *)(kUsed), #(aUsed), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)isUsed {
return [objc_getAssociatedObject(self, (__bridge const void *)(kUsed)) boolValue];
}
#end
ViewController.m
#import "ViewController.h"
#import "ARCTextbook.h"
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
ARCTextbook *t = [[ARCTextbook alloc] init];
t.studentID = 2;
t.used = YES;
}
#end

iOS: Object returning *nil description* after alloc and init

Let me preface this question by saying that I believe it to be a memory management mistake on my end. I just can't seem to figure out why it is happening.
I have a viewcontroller and a model class named Part.
#import <Foundation/Foundation.h>
#interface Part : NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSString *partType;
#property (nonatomic, strong) NSString *description;
#property (nonatomic, strong) NSNumber *price;
- (id)initWithName:(NSString *)name AndType:(NSString *)type;
#end
In the view controller I have a property set as follows:
#property (nonatomic, strong) Part *part;
In the init function of ViewController I create some static arrays and create objects out of them:
- (id)init {
self = [super init];
self.partList = [[NSMutableArray alloc] init];
NSArray *inputArray = #[#"Part1",
#"Part2",
#"Part3",
#"Part4",
#"Part5",
#"Part6",
#"Part7",
#"Part8"];
NSString *tempType = #"PartCategory";
// Add dummy static data
for (int i = 0; i < [inputArray count]; i++) {
Part *partInput = [[Part alloc] initWithName:[inputArray objectAtIndex:i] AndType:tempType];
//partInput.name = [inputArray objectAtIndex:i];
//partInput.partType = tempType;
NSLog(#"Inserting Part %#", partInput);
[self.partList addObject:partInput];
}
return self;
}
The NSLog I call in that loop returns Inserting Part *nil description* for every part. I just can't track down what is happening here.
EDIT: Here is the initWithName method from Part that the controller uses:
- (id)initWithName:(NSString *)name AndType:(NSString *)type {
if(self = [super init]) {
self.name = name;
self.partType = type;
}
return self;
}
When using %# to print NSObject, it calls debugDescription that by default calling the description method of that object and your Part object always have nil description.
You better solve this by changing the description property name to something else, because it conflicts with the description method of NSObject.
See also: NSObject description and debugDescription

Three20 TTPhotoViewController is not displaying photos

I have gone through a few tutorials including the sample app included
with Three20 and cannot figure out why photos aren't showing up in my
TTPhotoViewController. I actually find it pretty hard to debug.
Below is the code I have. Any thoughts on why images will not load
and how to debug it would be great. I get a completely black view in
between my bottom tabbar and upper nav bar. I also see left and right
arrows overlayed on the black view which seems to be for navigating
photos although I thought it was supposed to display a thumbnail
gallery.
// A TTPhoto class
// Photo.h
#import <Foundation/Foundation.h>
#import <Three20/Three20.h>
#interface Photo : NSObject <TTPhoto> {
NSString *_caption;
NSString *_urlLarge;
NSString *_urlSmall;
NSString *_urlThumb;
id <TTPhotoSource> _photoSource;
CGSize _size;
NSInteger _index;
}
#property (nonatomic, copy) NSString *caption;
#property (nonatomic, copy) NSString *urlLarge;
#property (nonatomic, copy) NSString *urlSmall;
#property (nonatomic, copy) NSString *urlThumb;
#property (nonatomic, assign) id <TTPhotoSource> photoSource;
#property (nonatomic) CGSize size;
#property (nonatomic) NSInteger index;
- (id)initWithCaption:(NSString *)caption urlLarge:(NSString
*)urlLarge urlSmall:(NSString *)urlSmall urlThumb:(NSString *)urlThumb
size:(CGSize)size;
#end
// Photo.m
#import "Photo.h"
#implementation Photo
#synthesize caption = _caption;
#synthesize urlLarge = _urlLarge;
#synthesize urlSmall = _urlSmall;
#synthesize urlThumb = _urlThumb;
#synthesize photoSource = _photoSource;
#synthesize size = _size;
#synthesize index = _index;
- (id)initWithCaption:(NSString *)caption urlLarge:(NSString
*)urlLarge urlSmall:(NSString *)urlSmall urlThumb:(NSString *)urlThumb
size:(CGSize)size {
if ((self = [super init])) {
self.caption = caption;
self.urlLarge = urlLarge;
self.urlSmall = urlSmall;
self.urlThumb = urlThumb;
self.size = size;
self.index = NSIntegerMax;
self.photoSource = nil;
}
return self;
}
- (void) dealloc {
self.caption = nil;
self.urlLarge = nil;
self.urlSmall = nil;
self.urlThumb = nil;
[super dealloc];
}
#pragma mark TTPhoto
- (NSString*)URLForVersion:(TTPhotoVersion)version {
switch (version) {
case TTPhotoVersionLarge:
return _urlLarge;
case TTPhotoVersionMedium:
return _urlLarge;
case TTPhotoVersionSmall:
return _urlSmall;
case TTPhotoVersionThumbnail:
return _urlThumb;
default:
return nil;
}
}
#end
// A TTPhotoSource class
// PhotoSet.h
#import <Foundation/Foundation.h>
#import "Three20/Three20.h"
#interface PhotoSet : TTURLRequestModel <TTPhotoSource> {
NSString *_title;
NSArray *_photos;
NSArray* _tempPhotos;
NSTimer* _fakeLoadTimer;
}
#property (nonatomic, copy) NSString *title;
#property (nonatomic, retain) NSArray *photos;
- (id) init;
#end
// PhotoSet.m
#import "PhotoSet.h"
#import "Photo.h"
#implementation PhotoSet
#synthesize title = _title;
#synthesize photos = _photos;
- (id) init {
_title = #"Test photo album";
_photos = [[NSArray alloc] initWithObjects:
[[[Photo alloc] initWithCaption:#"coming soon"
urlLarge:#"http://farm5.static.flickr.com/
4066/4653156849_0905e6b58e_o.jpg"
urlSmall:#"http://farm5.static.flickr.com/
4066/4653156849_0d15f0e3f0_s.jpg"
urlThumb:#"http://farm5.static.flickr.com/
4066/4653156849_0d15f0e3f0_s.jpg"
size:CGSizeMake(220, 112)] autorelease],
[[[Photo alloc] initWithCaption:#"coming soon 2"
urlLarge:#"http://farm5.static.flickr.com/
4023/4653774402_05e6acd995_o.jpg"
urlSmall:#"http://farm5.static.flickr.com/
4009/4653157237_c2f5f59e0d_s.jpg"
urlThumb:#"http://farm5.static.flickr.com/
4009/4653157237_c2f5f59e0d_s.jpg"
size:CGSizeMake(220, 112)] autorelease],
[[[Photo alloc] initWithCaption:#"coming soon 2"
urlLarge:#"http://farm5.static.flickr.com/
4023/4653774402_05e6acd995_o.jpg"
urlSmall:#"http://farm5.static.flickr.com/
4009/4653157237_c2f5f59e0d_s.jpg"
urlThumb:#"http://farm5.static.flickr.com/
4009/4653157237_c2f5f59e0d_s.jpg"
size:CGSizeMake(220, 112)] autorelease],
[[[Photo alloc] initWithCaption:#"coming soon 2"
urlLarge:#"http://farm5.static.flickr.com/
4023/4653774402_05e6acd995_o.jpg"
urlSmall:#"http://farm5.static.flickr.com/
4009/4653157237_c2f5f59e0d_s.jpg"
urlThumb:#"http://farm5.static.flickr.com/
4009/4653157237_c2f5f59e0d_s.jpg"
size:CGSizeMake(220, 112)] autorelease],
nil];
for (int i = 0; i < _photos.count; ++i) {
id<TTPhoto> photo = [_photos objectAtIndex:i];
if ((NSNull*)photo != [NSNull null]) {
NSLog(#"in here 65434");
photo.photoSource = self;
photo.index = i;
}
}
return self;
}
- (void) dealloc {
self.title = nil;
self.photos = nil;
[super dealloc];
}
#pragma mark TTModel
- (BOOL)isLoading {
return NO;
}
- (BOOL)isLoaded {
return YES;
}
#pragma mark TTPhotoSource
- (NSInteger)numberOfPhotos {
return _photos.count;
}
- (NSInteger)maxPhotoIndex {
return _photos.count-1;
}
- (id<TTPhoto>)photoAtIndex:(NSInteger)photoIndex {
if (photoIndex < _photos.count) {
return [_photos objectAtIndex:photoIndex];
} else {
return nil;
}
}
#end
// A TTPhotoViewController
// EventDetailViewController.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <Three20/Three20.h>
#import "PhotoSet.h"
#class Event;
#interface EventDetailViewController :
TTPhotoViewController<UINavigationControllerDelegate,
UIImagePickerControllerDelegate> {
NSArray *photos;
Event *event;
PhotoSet *_photoSet;
}
#property (nonatomic, retain) NSArray *photos;
#property (nonatomic, retain) Event *event;
#property (nonatomic, retain) PhotoSet *photoSet;
- (id)initWithEvent:(Event *)e;
// EventDetailViewController.m
#import "EventDetailViewController.h"
#import "Event.h"
#import "PhotoSet.h"
#import "Photo.h"
#implementation EventDetailViewController
#synthesize photos;
#synthesize event;
#synthesize photoSet = _photoSet;
#pragma mark -
#pragma mark Initialization
- (void)viewDidLoad {
self.photoSet = [[PhotoSet alloc] init];
self.photoSource = self.photoSet;
}
- (id)initWithEvent:(Event *)e {
if (self) {
self.event = e;
}
return self;
}
#end
You may find an answer here: http://www.raywenderlich.com/1430/how-to-use-the-three20-photo-viewer

Resources