Objective-C: What is a lazy class? - objective-c

Looking at the Objective-C runtime library source code, particularly at objc-runtime-new.mm, I saw some functions and even comments which referred to lazy and non-lazy classes. It seems that classes that don't have a +load method are called lazy classes, but I'm not sure of that and most likely that is not right. After searching on Google, I didn't found anything about lazy classes on Objective-C.
So, what is a lazy class in Objective-C? Does Obj-C have this feature? Is it related to the presence of a +load method in a class' implementation? At the file linked above, the runtime system calls a function called _getObjc2NonlazyClassList in order to get a list of non-lazy classes from an image. Why isn't there a _getObjc2LazyClassList function too?

I found the answer: It's all about a class implementing or not a +load method.
All the classes implemented in a given image file have a reference in a list stored in the "__DATA, __objc_classlist, regular, no_dead_strip" binary's section. This list allows the runtime system to keep track of all the classes stored in such file. However, not all of the classes need to be realized when the program starts up. That's why when a class implements a +load method, it also has a reference in a list stored in the "__DATA, __objc_nlclslist, regular, no_dead_strip" section.
So, _getObjc2NonlazyClassList retrieves the list of classes that do implement a +load method and are so called non-lazy. _getObjc2ClassList retrieves a list of all the classes in a image file, including the classes that don't have a +load method (and are called lazy) and the non-lazy ones. Non-lazy classes must be realized when the program starts up. Lazy classes, on the other hand, don't need to be realized immediately. This may be delayed until the class receives a message for the first time, for example (that's the reason for them to be considered "lazy").
The same is true for categories, by the way.

"Lazy" is used in two different contexts.
The first, when critiquing a class design, argues that a class is ineffectual -- that it doesn't do enough to justify its existence. People also call this kind of class "thin." This is probably not what you mean here.
Second, lazy evaluation and lazy instantiation mean that the class only does the work of evaluating a property or initializing itself when actually needed.
For example, suppose we have a class that makes an Employee object.
#implementation Employee
- (id) initWithID: (IdentificationCode*) ident
{
self =[super init]
if (self) {
_records=[self retrieveEmployeeRecordsFor: ident];
_identification=ident;
}
return self;
}
This is fine, but retrieving all the records from a database might be slow. And sometimes we don't need to do the work. For example:
- (BOOL) isFounder
{
if (indent.number<10) return YES;
return NO;
}
If we're instantiating an Employee simply to find out if they're a Founder, we don't need to look up their records at all!
.....
if ([thisEmployee isFounder]) {
[self sendCandyTo: thisEmployee.identification];
}
On the other hand, sometimes we need them:
- (NSArray*) payments
{
return [self.records retrievePayStubs];
}
So, if we're constructing an Employee just to call isFounder, we waste a database lookup. But we can't just skip that, because payments needs it.
What we do is take the database lookup out of the constructor and put it in a load method.
- (void) load
{
if (records) return;
self.records=[self retrieveEmployeeRecordsFor: ident];
}
- (NSArray*) payments
{
[self load];
return [self.records retrievePayStubs];
}
Now, we only load the employee records when we actually need them. If they've already been loaded, we don't do any extra work (aside from one method call). If we never need the payment records, then we don't need to do the work at all.
The class only works when it has to -- and waits 'til the last minute to do the work. It's "lazy!"

Here's a pattern base on a couple of DataImporter & a DataManager the first initializing is data property only when the second request the property
#interface DataImporter: NSObject
#property (readonly) NSString* data;
#end
#implementation DataImporter
#synthesize data;
-(id)init {
if (!(self = [super init])) { return nil; }
_NSLog(#"%#", #"Importing...");
data = #"DATA";
_NSLog(#"%#", #"Importation completed!");
return self;
}
#end
#interface DataManager: NSObject {
#private
DataImporter* _importer;
}
-(NSString*)loadData;
#end
#implementation DataManager
-(id)init {
if (!(self = [super init])) { return nil; }
_NSLog(#"DataManager initialized%#",#"!");
return self;
}
-(NSString*)loadData {
if (!_importer) {
_importer = [DataImporter new];
}
return _importer.data;
}
#end
DataManager* dm = [DataManager new]; //>> DataManager initialized
NSString* data = [dm loadData]; //>> Importing
//>> Importation completed!
_NSLog(#"%#", data); //>> DATA)

Related

In Objective-C how do you entirely replace a method of a parent class, while preserving that parent method's inherited functionality?

Basically I have a class hierarchy something like this:
NSObject
MySpecialController
MyExtraSpecialController
Each of these has an init method, and each implementation calls super first to let the superclass initialize itself first, all the way up the chain. For lack of better terminology I would say that each class "augments" its super class' behaviour.
But let's suppose I want to "replace" my super class's behaviour entirely (simply because I want to specialize it further for a particular app, but without cluttering the generic reusable super class. So it is assumed that I have intimate knowledge of the super class). The actual change that I want to do is replace a property with one of a more specific class type. To fully implement this I need the init method to instantiate an instance of widget of the appropriate class. So if I instantiate a MySpecialController, its widget property should be of type MySpecialWidget; but if I instantiate a MyExtraSpecialController, its widget should be of type MyExtraSpecialWidget:
//MySpecialController:
#interface MySpecialController : NSObject
#property (strong, nonatomic) MySpecialWidget *widget;
#end
#implementation MySpecialController
-(id)init {
if (self = [super init]) {
self.widget = [MySpecialWidget new];
}
}
#end
//MyExtraSpecialController:
#interface MyExtraSpecialController : MySpecialController
#property (strong, nonatomic) MyExtraSpecialWidget *widget;
#end
#implementation MyExtraSpecialController
-(id)init {
if (self = [super init]) {
self.widget = [MyExtraSpecialWidget new];
}
}
#end
Now this works in the sense that MySpecialController works, and can be used by anyone with the public API. And MyExtraSpecialController also works, and follows proper separation of concerns as it assumed nothing about the superclass's behaviour. This is the type of subclass one would create of a framework or library class: robust and unassuming.
What actually happens though is that when I create a new instance of MyExtraSpecialController, its superclass first instantiates a MySpecialWidget, and then it immediately deallocates that instance and replaces it with an instance of MyExtraSpecialWidget. Sure this works, but since I DO have intimate knowledge of the superclass (which basically means that I know exactly what its init method does, so I can safely replace it without needing to call it first), I want to avoid this problem and only instantiate a single widget (it just so happens that creating a widget is really expensive and isn't premature optimization). So I want to replace super's implementation entirely so that it doesn't create a widget, and will replace everything else that it does based on my intimate knowledge, but, and this is key, I still want to call init further up the chain because I don't know what my replaced class' superclass' init method does (NSObject in this case), as this is a class I don't have intimate knowledge of.
The immediate solution that comes to mind is to use the Objective-C dynamic runtime to get hold of the grandparent instance, and just call its init (which will then take care of calling up the chain if it needs to), therewith bypassing super. But whenever I find myself about to do something like that I always wonder if there is a better approach altogether--conceptually speaking, i.e. to replace rather than augment a superclass' method. Is there?
You could remove the instantiation of self.widget from the init functions and implement a custom "lazy" getter function instead:
- (MySpecialWidget *)widget
{
if (_widget == nil) {
_wigdet = [MySpecialWidget new];
}
return _widget;
}
Then you can override this method in the subclass. The widget will be created on the first access to self.widget, and either the superclass or the subclass getter is called.
One easy way to solve this would be to create a hook for making the widget.
#implementation MySpecialController
-(id)init {
if (self = [super init]) {
self.widget = [self makeWidget];
}
}
- (MySpecialWidget*) makeWidget
{
[MySpecialWidget new];
#end
Then your subclass can override makeWidget to return a VerySpecialWidget. This makes sense when you don't want clients to know about these widgets.
In your scenario, it's possible that clients know something about the widgets -- e.g. they want a VerySpecialController in order to get a VerySpecialWidget. If that's the case, you might want to let the client pick the widget:
[MySpecialController initWith: [MyVerySpecialWidget new]];
If the widget is the primary force for making the subclass, either approach may eliminate the need to sprout the subclass in the first place.
The second approach has the additional advantage of making unit testing easier; you can build a MySpecialController and pass it a dummy, stub, or mock without any fuss:
[MySpecialController initWith: [MyTestObjectThatPretendsToBeAWidget new]];
But the first pattern is cleaner if the clients shouldn't know anything about widgets.
One approach is to add an instance method -widgetClass to MySpecialController
#implementation MySpecialController
- (id)init
{
self = [super init];
if (self) {
self.widget = [[[self widgetClass] alloc] init];
}
return self;
}
- (id)widgetClass
{
return [MySpecialWidget class];
}
//...
#end
and override that method in MyExtraSpecialController
#implementation MyExtraSpecialController
- (id)widgetClass
{
return [MyExtraSpecialWidget class];
}
//...
#end

Updating view with a data from the method of another class

I am trying to update my UIProgressView with some data from a method of my utility class.
Now, just because for updating my UIProgressView, i am holding that method in my view controller class and everything works fine. Because i can reach the loop in that method with a global variable so i can update my progress. But if i want to move this method to my utility class, what am i supposed to do to keep informed my UIProgressView. Thanks.
What I would suggest is to redesign your utility class to be a singleton
Here is an example of code of your utility class:
UtilityClass.h file:
#interface UtilityClass : NSObject
+ (UtilityClass *)sharedInstance;
- (CGFloat)awesomeMehod;
#end
UtilityClass.m
#implementation UtilityClass
+ (id)sharedInstance
{
static UtilityClass *_instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[UtilityClass alloc] init];
});
return _instance;
}
- (id)init
{
self = [super init];
if (!self) return nil;
// Regular initialization, however keep in mind that it will be executed just once
return self;
}
- (CGFloat)awesomeMethod
{
return 42.0f
}
#end
Now from your view controller you will call
CGFloat progress = [[UtilityClass sharedInstance] awesomeMethod];
[self.progressView setProgress:progress];
keep in mind several things:
It's one of possible approaches and I would go and read about various
design patterns that might come in handy one day
Probably a good idea to refresh knowledge on view controllers and the way they interact
For class to become a proper singleton, you also should override
methods such as alloc, init, initWithZone, dealloc, release
etc (list of methods to override will vary if you use ARC), here is
an example of doing that, although dispatch_once takes care of
#synchronize() call. For now, as long as you "instantiate" you class only
through calling sharedInstance class method you will be fine.

singleton in multi document

i used to using singleton like that:
///.h
#interface ASMyController:NSViewController
+(id)myViewController;
#end
////.m
static ASMyController* singleton = nil;
#implementation ASMyController
+(id)myViewController
{
if(nil == singleton)
{
singleton = [[[self class] alloc] init];
}
return singleton;
}
-(id)init
{
self = [super initWithNibName:#"test" bundle:xxxx];
if(self)
{
..............................
}
return self;
}
#end
The singleton work well in non-document-base application.However, in document - base Application, each instance of app share the same static variable. In my first design, the singleton one and only in a app instance but not all app instances.
So is it mean that I should reconsider the design ? Or I can make the singleton to a dict. and I can use key to get a singleton of current instance? Or any other good idea for me?
I pray that my poor English will not trouble u..
The very name of your method, my..., suggests something rather fundamental is being misunderstood - there is just one singleton shared by everybody, objects don't own their own copies of singletons.
A singleton is not a way to avoid a variable, it appears you might be trying to use [ASMyController myViewController] instead of an instance variable self->myViewController (often abbreviated to myViewController) or a property self.myViewController.
You probably need to look at something along the lines of:
#interface ASMyDocument : NSDocument
{
ASMyContoller *myViewController;
}
However your original design suggests you should really review the relationships between/meanings of classes, instances, singletons, has-a, is-a etc.

singleton in objective c

I saw a singleton example on objective-c book. However, I don't know if there is difference of meaning of 'singleton' definition between objective-c and other langs. Can this [[SingletonClass alloc] init] still be used to create a new object? If yes, how to guarantee there is only one object in the memory?
#import "SingletonClass.h"
#implementation SingletonClass
static SingletonClass *sharedInstance = nil;
// Get the shared instance and create it if necessary.
+ (SingletonClass*)sharedInstance {
if (sharedInstance == nil) {
sharedInstance = [[super allocWithZone:NULL] init];
}
return sharedInstance;
}
// We can still have a regular init method, that will get called the first time the Singleton is used.
- (id)init
{
self = [super init];
if (self) {
// Work your initialising magic here as you normally would
}
return self;
}
If you want a true singleton, i.e. an object that can be instantiated only once, take a look at Apple's documentation: Creating a Singleton Instance.
Basically, the idea is to override a number of methods related to allocating and managing objects: +allocWithZone (which is called by +alloc), -retain, -release, -copyWithZone, etc., so that it becomes quite difficult to create more than one instance of your singleton class. (It's still possible to create a second instance by calling the runtime directly, but this should be enough to get the point across.)
Pretty much every blogger who has ever written about Objective-C in any capacity has offered an opinion on how to implement singletons. Many of those opinions seem pretty good, and most of them are fairly similar. It's clear that Dave DeLong knows what he's talking about, and his piece on singletons is short, sweet, and gets straight to the point.
I don't know if there is difference of meaning of 'singleton' definition between objective-c and other langs.
It follows the common definition of languages derived from C.
Can this [[SingletonClass alloc] init] still be used to create a new object?
Yes
If yes, how to guarantee there is only one object in the memory?
Avoid enforcing the pattern (e.g. do not force it to be a singleton). Just make a normal object. Then if you really want only one instance, create an instance and save it someplace for reuse (your app delegate is one typical place for this, because it is typically created once per execution).
In practice, most (>95%) ObjC singleton implementations i've seen in the wild are used for the wrong reasons, and would have been better or as good as normal objects.
Every solution linked in the answers so far has (at minimum) subtle problems, dangers, or undesirable side-effects.
There is no language support for singletons, but you can do it by hand. Look at the singleton example here. It doesn't look like it is thread-safe, though. I would allocate the object in +initialize instead of +sharedManager.
You can create a singleton in Objective-C by doing the following:
+(MyAPI *)shared {
static dispatch_once_t queue;
static MyAPI *singleton = nil;
dispatch_once(&queue, ^{
singleton = [[MyAPI alloc] init];
});
return singleton;
}
This will also ensure that it is thread safe. Without using the dispatch_once you run the risk of multiple threads trying to access it at the same time when one is in the middle of allocating it, and the other is trying to use it.
Singleton class is used to save the data for use anywhere in app.
//SingletonObject
#define saveDataSingletonObject ((SaveDataSingleton*)[SaveDataSingleton sharedManager])
#interface SaveDataSingleton : NSObject
#property (nonatomic,strong) NSMutableArray *DataArr;
+ (id)sharedManager;
-(void)clearAllSaveData;
#end
#implementation SaveDataSingleton
#synthesize DataArr;
+ (id)sharedManager {
static SaveDataSingleton *sharedManager;
if(!sharedManager) {
#synchronized(sharedManager) {
sharedManager = [SaveDataSingleton new];
}
}
return sharedManager;
}
-(void)clearAllSaveData{
DataArr=nil;
}
- (id)init {
if (self = [super init]) {
DataArr = [[NSMutableArray alloc]init];
}
return self;
}
// using setter getter save and retrieve data
+(void)setDataArr:(NSMutableArray *)Dataarr
{
self.DataArr = [[NSMutableArray alloc]initWithArray:Dataarr];
}
+(NSMutableArray *)DataArr
{
return self.DataArr;
}
#end
Save and Retrieve data // Use singleton Object
// save data using setter function.
[saveDataSingletonObject setDataArr:Array];
//fetch data using getter function.
NSArray *arr=[saveDataSingletonObject DataArr];

Singleton or Class methods [duplicate]

This question already has answers here:
What does #synchronized() do as a singleton method in objective C?
(6 answers)
Closed 3 years ago.
After reading the responses to a question about singletons in Objective C it appears that each solution makes some tradeoff in regards to threading in the instance accessor. i.e.
#synchronized(self)
{
if (sharedInstance == nil)
sharedInstance = [[MySingleton alloc] init];
}
return sharedInstance;
This essentially single-threads access to the singleton, and if it's something that's used frequently in an operation, seems like something that could cause threads to unnecessarily contend.
What's the downside to simply using the class object as the singleton instance, and exposing functionality via class methods, i.e.
#interface MySingleton : NSObject {
}
+ (void)doSomething;
#end
#implementation MySingleton
+ (void)initialize {
//do some setup if necessary
}
+ (void)doSomething {
//do something
}
#end
In this way we avoid doing the lock + check every time we want to reference the singleton object and we can also eliminate having to store it in a local or method ivar.
This approach also lets the runtime guarantee that only one instance (the Class object) exists in the system at any given time.
EDIT
There's more here than just threading, with a traditional singleton you usually write code like this:
MySingleton *instance = [MySingleton getSharedInstance];
NSObject *someResult = [instance getResult];
//or
if (instance.someProperty) {
//do something
}
However if your singleton is a class instance, you essentially eliminate the need call getSharedInstance all the time. Consider this code:
NSObject *someResult = [MySingleton getResult];
//or
if ([MySingleton someProperty]) {
//do something
}
I hear the point that you have to store your data in file local static variables, or in global variables (yuck). But it's really not all that different from a traditional singleton with the exception that you lose Objective-C 2.0 properties (instead you have to use traditional accessor methods).
Here's one key tradeoff for me that seems like a win. In a traditional singleton you end up overriding -copyWithZone, +allocWithZone, -retain, -retainCount, -release and -autorelease if you really want to get things right.
This seems like an awful lot of work to do every time you want to write a simple Singleton object (they happen to be pretty useful). So why not simply just replace it with this:
#implementation MySingleton
+ (void)initialize {
//do your setup
}
- (id)init {
NSAssert(NO, #"You should read the documentation on singletons.");
}
#end
It's a lot lighter in terms of code, and unless your consumers are really sneaky they won't ever create two instances.
Get to the point already
My question is really this:
Is there any drawback to using the Class object as the instance of your singleton?
It seems like you can take all the same steps in terms of threadsafety, memory efficiency etc. without having to remember to override so many methods and accessors or litter your code with instance checks.
With iOS 4.0 or later, by far the best solution is to just use dispatch_once, as in
+ (id)sharedInstance {
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
sharedInstance = [[MyClass alloc] init];
});
return sharedInstance;
}
You may also want to consider using a single dispatch_queue to serialize access to the internals of a class. If all your public methods just run a block on the same dispatch_queue then you won't have to worry about concurrency issues.
This is my first post on Stack Overflow... (so prepare for stupidity)
I think there is a hybrid solution that might be useful.
I want to set and get (global) values out of a singleton class without having calling "getSharedInstance". I'd want the code to look like this...
frameRate = Singleton.frameRate;
Singleton.frameRate = 42;
To achieve this, each variable we need to store in the singleton has a getter and setter class method. The class method then goes to an instance to store the data in an ivar. The instance isn't directly accessed by the main program.
The getter looks like this:
+ (int) frameRate
{
return [[Singleton instance] ivarFrameRate];
}
The (ugly) instance call is hidden inside the class code.
By calling the instance method here, the class method will automatically instantiate an object when first used. Once the singleton is instantiated, the instance stores ivars conventionally. Here, I am prefixing with "ivar" make the ivar explicit.
#property int ivarFrameRate;
and
#synthesize ivarFrameRate;
This automatically creates conventional getter (and setter) methods to access the ivar.
(edit - here is a complete example)
// Singleton.h
#import <Foundation/Foundation.h>
#interface Singleton : NSObject
{
float ivarFrameRate
}
#property float ivarFrameRate;
- (id) init;
+ (Singleton *) instance;
+ (float) frameRate;
+ (void) setFrameRate:(float)fr;
#end
and
// Singleton.m
#import "Singleton.h"
#implementation Singleton
#synthesize ivarFrameRate;
static Singleton* gInstance = NULL;
+ (Singleton*)instance
{
#synchronized(self)
{
if (gInstance == NULL)
gInstance = [[self alloc] init];
}
return(gInstance);
}
- (id)init
{
self = [super init];
return self;
}
+ (float) frameRate
{
return [[Singleton instance] ivarFrameRate];
}
+ (void) setFrameRate:(float)fr;
{
[[Singleton instance] setIvarFrameRate:fr];
}
This is fine, but still just changes your circumstances rather than fixes your problems. Unless you don't have any actual data tied to your singleton, in which case this will work just fine. Anytime you access central data you will need to properly make it thread-safe.
Additionally, without some kind of iVar I don't know of a way to store data (that is intended) directly in a class.
In the example above I would code it in this way, getting the same result as you are proposing and only taking the performance hit if we are creating/re-creating the singleton:
if (sharedInstance)
return sharedInstance;
#synchronized(self)
{
if (sharedInstance == nil)
sharedInstance = [[MySingleton alloc] init];
}
return sharedInstance;
Keep in mind that either way, if you are accessing data that is potentially changing on different threads then you'll have to make that code thread-safe anyway, either with very careful planning or using code to ensure there are no problems. I'd recommend a mix, but when in doubt the latter when at all possible. =)
If you use a class as your singleton, the only way to store data would be to use static file variables and global variables. If you are going to go so far that you make a class you don't plan to instantiate, you might as well just use standard C functions:
void doSomething(void);
void doSomething() {
//do something
}