I've got a problem with this code.
#class CatalogMenu;
#class SettingsMenu;
#interface TabBar : UIViewController {
CatalogMenu *catalogMasterView;
SettingsMenu *settingsMasterView;
}
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#property (nonatomic, retain) IBOutlet CatalogMenu *catalogMasterView;
#property (nonatomic, retain) IBOutlet SettingsMenu *settingsMasterView;
I got a UIViewController subclass, which implements the interface at the top. To use my classes in this UIViewController i've imported the two classes CatalogMenu and SettingsMenu. The problem is, that all the variables are null after synthesizing. That means, that they all got no address in the memory.
The problem disappears if i change the subclass to NSObject. But this can't be the answer, because then i cant use the UIViewController functions.
Is this a known problem?
Synthesizing doesn't actually allocate your variables which is why they are null, it just provides the Getter/Setter methods for accessing the variables. In your init method in the TabBar class you need to allocate your catalogMasterView and settingsMasterView
Related
I declared a UIView in the objective-C Class File (Test.m)
#property (nonatomic,strong) UIView *Scene1;
In the StoryBoard, when I am trying to make a reference outlet pointing to the view I set in the objective-C file, Scene 1 is not displayed in the list.
Note: 1. I have already pointed the view to the correct class file.
2. They are all UIView type
Here's the code of the header file (Test.h)
#import "JSMessagesViewController.h"
#interface Test : JSMessagesViewController
#end
Here's the code for the Class File Test.m
#import "Test.h"
#import "MessageData.h"
#interface DeerView () <JSMessagesViewDelegate, JSMessagesViewDataSource, UIImagePickerControllerDelegate, UINavigationControllerDelegate,UIActionSheetDelegate>
#property (strong, nonatomic) NSMutableArray *messageArray;
#property (nonatomic,strong) UIImage *willSendImage;
#property (nonatomic,strong) UIView *Scene1;
#end
#implementation DeerView
#synthesize messageArray, NameInput, Scene1, Scene2, Scene3, Scene4, Name;
...
#end
I am a high school student and a young developer who is still learning more. Hope you can help with my question.
Change your declaration of outlet and mark it as outlet
#property (nonatomic, weak) IBOutlet UIView *Scene1;
And you don't need to declare it as a strong property if you won't remove it from subview.
I'm developing for iOS 7 but I still have to manually write getters otherwise my properties just don't get initialized. I tried to manually synthesize those properties, even though that shouldn't be needed anymore, but that doesn't do it.
In my view controller below, I use the property motionTracker, which never gets initialized. I have the same issue with all my projects, so I know it's a misunderstanding on my part.
#import "ViewController.h"
#import "TracksMotion.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UIButton *startRecording;
#property (weak, nonatomic) IBOutlet UIButton *stopRecording;
#property (strong, nonatomic) TracksMotion *motionTracker;
#end
#implementation ViewController
#synthesize motionTracker = _motionTracker;
- (void)startMyMotionDetect
{
[self.motionTracker startsTrackingMotion];
}
#end
The motionTracker has a public API for the method startsTrackingMotion so I don't know why this doesn't work.
#import <Foundation/Foundation.h>
#import <CoreMotion/CoreMotion.h>
#interface TracksMotion : NSObject
- (void)startsTrackingMotion;
- (void)stopTrackingMotion;
#property (strong, nonatomic) CMMotionManager *motionManager;
#end
Properties / instance variables are not magically initialized for you. When you say:
#property (strong, nonatomic) TracksMotion *motionTracker;
... you are just reserving memory space for an instance variable (and generating a getter and a setter method through #synthesize or autosynthesis). There is no actual TracksMotion object there until you put one there. You must write code to do that. You must create or obtain a TracksMotion instance and assign it to self.motionTracker at some point, presumably early in the life of self (in this case, that's a ViewController instance). Until you run code that does that, self.motionTracker is nil.
(It is possible that you are being confused because it looks like outlets are automatically initialized. For example, you've got #property (weak, nonatomic) IBOutlet UIButton *startRecording; And sure enough, self.startRecording is a button. But that's because the nib-loading process does for you the very thing I'm saying you must do: it makes a button from the storyboard or .xib file, and assigns it to this instance variable.)
Just when you think you understand something, you don't! :)
I understand that if I make a variable a property, I can access it anywhere in the Class and even set it from outside that class.
I thought if I didnt need it I could just make it an ivar. So I have a viewcontroller with about 5 UILabels. So in its viewDidLoad I say:
pharmacyName.text = self.receivedLocation.name;
pharmacyTel1.text = #"556-7843";
pharmacyTel2.text = #"991-2345";
pharmacyTel3.text = #"800-0001";
When I have declared them like so in the .h file:
#interface DetailViewController : UIViewController{
IBOutlet UILabel *pharmacyName;
IBOutlet UILabel *pharmacyTel1;
IBOutlet UILabel *pharmacyTel2;
IBOutlet UILabel *pharmacyTel3;
}
#property (nonatomic,strong) MyLocation *receivedLocation;
#end
No. Its not mandatory to create ivar as property. If you don't want to access it outside of class just use as it is. In ARC you can also declare your IBOutlet as below:
#interface DetailViewController : UIViewController{
__weak IBOutlet UILabel *pharmacyName;
__weak IBOutlet UILabel *pharmacyTel1;
__weak IBOutlet UILabel *pharmacyTel2;
__weak IBOutlet UILabel *pharmacyTel3;
}
This will keep a week reference of outlets. Here is detail of __weak and strong
There are always many ways you can approach programming tasks and standards. Our group has started using a few coding standards. We like to put our instance variables that are NOT accessed from outside the class (and protocol statements) in the private interface in the .m file like this:
#interface DetailViewController() {
NSString *value_;
}
#end
We also like to use #property for our instance ivars and declare those in the private interface as well like this:
#interface DetailViewController() {
}
#property (nonatomic, strong) IBOutlet UIlabel *pharmacyName;
#end
and then in your code, you would refer to this as self.pharmacyName. It seems to work pretty well with autocomplete, and with getting and setting. Also when you have thread safety issues, the nonatomic, strong behavior comes in handy.
What is the technical difference between them and which is the method recommended by Apple?
// 1
#interface CocoaQuizViewController : UIViewController
{
IBOutlet UILabel *myLabel;
}
#end
// 2
#interface CocoaQuizViewController : UIViewController
{
IBOutlet UILabel *myLabel;
}
#property (nonatomic, retain) IBOutlet UILabel *myLabel;
#end
// 3
#interface CocoaQuizViewController : UIViewController
{
UILabel *myLabel;
}
#property (nonatomic, retain) IBOutlet UILabel *myLabel;
#end
// 4
#interface CocoaQuizViewController : UIViewController
#property (nonatomic, retain) IBOutlet UILabel *myLabel;
#end
The default is (generated automatically if you drag and drop outlet directly from xib to source class):
#interface CocoaQuizViewController : UIViewController
#property (nonatomic, weak) IBOutlet UILabel *myLabel;
#end
All are quite OK.
With new LLVM you are supposed to do 4th one.
#interface CocoaQuizViewController : UIViewController
#property (nonatomic, retain) IBOutlet UILabel *myLabel;
//even you use strong and weak intead of retain,assign,copy
#end
In earlier days, you were doing 1, 2 and 3. Now most of the thing is atomatcally done by the compiler. So your work is now easier than never before.
With New Compiler which comes with XCode4.4 and onwards gives you auto-synthesize for all the properties you declare. ivars also get created prefixed with your property name.
The 4th one, Because Now Apple has recommended all developers to make use of properties.
A couple of thoughts:
Your fourth example avoids a whole category of possible bugs that can plague the first three examples, where you can accidentally end up with two ivars (e.g. if you omitted the #synthesize, the compiler would generate an ivar called _myLabel, your myLabel ivar wouldn't be used, and, thus, would end up being redundant and only serve as a possible source of confusion).
If you use ARC (which I'd encourage, if you can), then clearly that retain reference becomes weak.
You probably shouldn't be "writing" the IBOutlet code yourself anyway. It's just an opportunity to introduce a bug. In IB, click on the "assistant editor" to show your code while working on IB, and then control-drag (or right-click-drag) from the control to the code, and IB will write your code for you! See https://stackoverflow.com/a/15551101/1271826 for screen snapshots.
For example one, I declare an object inside the interface brace {} like:
#interface testViewController : UIViewController {
IBOutlet UILabel * myLabel;
}
#property (retain, nonatomic) UILabel *myLabel;
#end
and example two, I declare an object outside the inferface brace {} like:
#interface testViewController : UIViewController {
}
#property (retain, nonatomic) IBOutlet UILabel *myLabel;
#end
I run the code and the result is the same, so I want to ask what is the different for decalare an object inside or outside the interface brace {}?
Thanks
The modern Objective-C runtimes (64-bit Mac OS X and iOS) will generate the backing store for your declared properties when you #synthesize them. So you don't need to declare them within the braces.
If you are declaring an iVar that is not a property and will only be used by the class, then they need to be declared. It's a good idea to mark these #private e.g
#interface MyClass : NSObject {
#private
NSString *privateString;
}
#property (nonatomic, copy) NSString *publicString; // be sure to #synthesize this
#end
In the second example you only declare a property. Xcode will declare object automatically.