iOS global object without having to import header - objective-c

I use singletons often when I need to have a shared instance object across multiple controllers. However, what I don't like is that I still have to import the singleton header at the top of a class whenever I want to use it.
Is there anyway to create an object that's only instantiated once at runtime that all classes can access globally without having to import it?

well, you could just throw #import "MONSingleton.h" in the prefix header... just don't get too carried away, because it can make your build times unnecessary long*.
*or shorter, if used correctly.

Related

Why can't I access objective-c methods even though file is in bridge?

I have a project with a lot of objective-c code. Now I would like to access that code in my swift files. But for some reason I can't access the objective-c methods even though I can initiate an object of that class.
I have a bridge-file with all the .h files added called projectName-Bridge-Header.h
#import "NumberVerificationViewController.h"
And it's path is added in the build-settings (a side question: I can initiate an object from a class even though the bridge path isn't added to the build-settings. Why is that?):
I can initialize an object from the class, but I can't access the method:
var num = NumberVerificationViewController()
num.numberVerificationCallCompleted
The last line gives error that method does not exist.
I'm new to objective-c so it might be something really simple. Still, it's beyond me.
At first glance, it looks like you might be missing the declaration in the .h file to make the method public.
NumberVerificationViewController.h
-(void)numberVerificationCallCompleted:(NSNumber*)responseNumber;
NumberVerificationViewController.m
-(void)numberVerificationCallCompleted:(NSNumber*)responseNumber {
...
}

how to make methods in category classes available to other classes?

I want to use a class I got from iosframeworks.com called UIImage+ProportionalFill. I know it's a category extending UIImage, but when I try to use one of its methods in another class I get a message saying no visible #interface for UIImage declares the selector 'nameOfWhateverMethodIWantToUse'. I'm not surprised to get an error, since there must be more to using it than dropping it into XCode, but how do I make the methods in the new category/class available to other classes?
You just need to import your category in the class you like to use it...
#import "UIImage+ProportionalFill.h"
I usually do this in the header file.
The compiler needs to be able to see the declaration of the methods, which should be in the category's header file. You must import the header file wherever you want to use the methods.
You need to #import the header containing the method declaration(s) in each file that uses said methods.
Note tha the methos should be prefixed; i.e. -JDnameOfWhateverMethodIWantToUse.
Note also that adding categories to framework classes willy nilly can easily lead to a rather awfully architected application that becomes difficult to refactor/maintain.
Based on what you said, I think you just forgot to import it.
#import "UIImage+ProportionalFill.h"
Write it on the top of the .h file of the class where you want to use the method.

In Objective-C, do I need to import every h file to see my object hierarchy?

I've created an 3 objects, and chained them together:
Questionnaire object - which contains a
NextQuestion object - which contains an
Answer object - which has an text property.
In a ViewController, I want to be able to call:
NSString *thisAnswerText = Questionnaire.nextQuestion.answer.text;
However, to do this, I have to import all three files into my .m file
#import "Questionnaire.h"
#import "Question.h"
#import "Answer.h"
Is it necessary to import each of the objects that I use in each .m file? Or is there something I can do which means I only need to import the top level item and all it's children are automatically referenced?
NB. I know that I can add all three to the Prefix.pch file, but I was wondering if I'm missing some trick to Objective-C which allows me to declare one item and it's child objects become imported automatically?
THANK YOU!
When you import a .h file any imports within the .h file are also available. You may need to clean and rebuild but they should be available. So in your case no, you should be able to get away with importing the Questionaire.h only.
Also if you're app depends on those custom classes and they will be used all over the place, it can be a good idea to import them in your .pch file and they will be precompiled for all your classes.
Is it necessary to import each of the objects that I use in each .m file?
Not in all cases, but if you message an object, you should ensure the compiler sees its declaration -- just because ObjC is a very dynamic language.
Or is there something I can do which means I only need to import the top level item and all it's children are automatically referenced?
Yes, you could add an #import in any header (of course, the must be compatible with the translation). However, adding #imports should be minimized because #importing the world will increase your build times and introduce a bunch of dependency.
In the public header files for your interfaces, you should forward-declare as much as possible and only #import what is really needed. This will help to keep build times down. In your implementation files you can import anything you need.
Sometimes for usability's sake, you may which to collect multiple headers into a single "MyFramework.h" file so that you don't have to add 5 imports everytime you use a class. You should be careful with this however, because it can increase build times if the header is imported in many places.
You may also want to think about adding common imports to your prefix header (.pch) which can be precompiled by Xcode to improve build times a little.

Actionscript3 Clarification on Usage of Classes?

Hi I am quite new to actionscript 3 and I would like some clarification on the use of classes. I am trying to use a AS3Commons UI project from http://sibirjak.com. But I am unsure on how to use some of their classes. The way I have it formatted in one of my keyframes is:
import com.AlertBox; // The location of the alertbox class
import com.AlertTutorialStep1; // The location of the example AlertTutorialStep1 class
var alertbox:AlertTutorialStep1 = new com.AlertTutorialStep1; // Creating an instance of the example class in the AlertTutorialStep1 doc
alertbox.AlertTutorialStep1(); // Trying to access the AlertTutorialStep1() function which is in the AlertTutorialStep1 class
But I am unable to access the function AlertTutorialStep1() and unsure why I am getting the error, can someone provide me with some insight? http://sibirjak.com/osflash/blog/tutorial-creating-an-alert-box-with-the-as3commons-popupmanager/
Try and avoid using the timeline if possible. I think that OOP and the Flash timeline can work if you know what you're doing, but stackoverflow is full of questions from beginners struggling with the timeline and classes, and these tend to be difficult to debug. Try to set your project up with a single Main document class which instantiates all the other classes you need for your project.
That said, assuming you have the AlertBox and AlertTutorialStep1 classes, and their dependencies, in the right directories relative to it, I think your code will work if you set the document class of your .fla to the AlertBoxTutorial1 class.
Again assuming the packages are all set up correctly, you could try replacing your existing code with the following:
//import com.AlertBox; // Don't need to import this, AlertTutorialStep1 imports and uses it
import com.AlertTutorialStep1; // The location of the example AlertTutorialStep1 class
var alertbox:AlertTutorialStep1 = new AlertTutorialStep1(); // Don't need to fully qualify the class as it is already imported in the line above
this.addChild(alertbox); // Need to add the instance to the stage
//alertbox.AlertTutorialStep1(); // AlertTutorialStep1() is the constructor of the class and can't be invoked via an instance of it

Objective-C : Object declaration question

there is something I try to understand. I have this object declaration in my AppsController-Class for a Cocoa Application
NSMutableArray *personArray;
In can put this declaration inside the Header file or inside the implementation of the class in the code file. It makes no difference. I can even put it outside the #implementation context right under the #import commands.The Application works just fine.
Since I don't inherit from the AppsController Class or do anything else fancy with it I wonder what might be the difference between these types of declarations?
Where does the declaration really belong?
It depends on how you want to use the variable. If you place the variable declaration inside the interface for your class, each instance of your class will have its own copy of the variable, which is kept separate from all other instances of your class:
#interface AppsController : NSObject
{
NSMutableArray *personArray;
}
Each instance of the AppsController class will have its own copy of the personArray variable, which is separate from all other instances of the class.
If, however, you define the variable outside of the interface, it becomes a global variable, and it is a shared (instances of your class do not get their own copy), and can be accessed from any instance of your class. If you declare it in the header as such:
NSMutableArray *personArray;
it is also visible to methods in other files and classes that include your header.
If you declare the variable in the implementation file, but outside of the implementation itself, and prefix it with the static keyword, the variable will only be visible to the implementation of your class. This is common when you want a variable that is visible to you all of class instances, but not visible to anyone else, and is a way to create class variables.
Since your object is a controller object, I am guessing that you only have one instance of it present in your application. You should declare the variable either:
As an instance variable if your personArray variable needs to be unique to each instance of your controller class (even if you only have one instance now, you may have more than one instance of it in future).
As a class variable (using the static keyword) if you want the variable to be visible to all instances of your class, with only one, shared instance of the variable.
As a global variable if you want the variable to be a single instance (not unique to instances of your class) and also visible to other classes or code in other files.
You should probably put it in the interface section of the header file, that way there will be one instance of it per object instantiated. Which I presume is your intention.
I think if you put it elsewhere it will be treated as a global variable. Ie, there will only ever be one instance of personArray, and it will be visible from anywhere in your application.
Your application is probably working fine, because you only have one instance of your AppsController Class, and no other variables called personArray. If you ever need a second AppsController, or another variable elsewhere called personArray, you'll run into problems.
If you declare the variable in the implementation file, but outside of the implementation itself, and prefix it with the static keyword, the variable will only be visible to the implementation of your class. This is common when you want a variable that is visible to you all of class instances, but not visible to anyone else, and is a way to create class variables.
just to clarify, the reason variables declared inside the implementation file but outside the implementation section are not available outside the class, is because other classes are not aware of anything inside the implementation file. your import statements refer to headers, not their implementations, so they know nothing of those implementation file declarations.
anyway, to create a static variable accessible only by a class, use keyword static when making a declaration in an implementation file. you can put it at the top of the file, at the top of the implementation section, or inside a function, depending on what you want the scope to be.
edited: corrected, thanks peter