This question already has answers here:
What is the difference between ivars and properties in Objective-C
(2 answers)
Closed 8 years ago.
What is the difference between:
#interface PhotoAppViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
{
UIImageView * imageView;
UIButton * choosePhotoBtn;
UIButton * takePhotoBtn;
}
#property (nonatomic, retain) IBOutlet UIImageView * imageView;
#property (nonatomic, retain) IBOutlet UIButton * choosePhotoBtn;
#property (nonatomic, retain) IBOutlet UIButton * takePhotoBtn;
And this:
#interface PhotoAppViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
#property (nonatomic, retain) IBOutlet UIImageView * imageView;
#property (nonatomic, retain) IBOutlet UIButton * choosePhotoBtn;
#property (nonatomic, retain) IBOutlet UIButton * takePhotoBtn;
What do the curly braces mean after the delegation?
From http://rypress.com/tutorials/objective-c/properties.html:
An object’s properties let other objects inspect or change its state.
But, in a well-designed object-oriented program, it’s not possible to
directly access the internal state of an object. Instead, accessor
methods (getters and setters) are used as an abstraction for
interacting with the object’s underlying data.
Stackoverflow Answer
The "curly braces" are the scope in which instance variables, (also known as ivars) are defined. Properties are variables that can be publicly accessed (i.e. by other classes), whereas instance variables are private and can be only accessed in the scope of the class's implementation itself.
Read this and this to get an intuitive understanding about the differences between properties and ivars.
I'd strongly recommend reading Apple's documentation on Objective-C, or a good book on the same topic if the former turns out to a tad bit too technical for your taste.
Related
What made the difference
#property (strong, nonatomic) and #property (nonatomic, strong) in ios.
i will define iboutlet for example uilabel like this
#property (strong, nonatomic) IBOutlet UILabel *label1;
and i see many time in this site
#property (nonatomic, strong) NSString* str;
What is the difference between the two property.
There are no differences in the logic. They represent the same thing but with different order.
Usually in IBOutlets you have #property (weak, nonatomic) because it is auto generated when you ctrl+drag from interface builder.
However, most people prefer the second form because the "nonatomic" is used in most of the cases in ios and therefore it is easily ignored.
There is no difference. But in apple sample codes and most frequently we use :
#property (nonatomic, strong)
I added a UITextView to storyboard that I created a property for and connected in a subview of UIView (called FieldView) in this case. The property was like this
#property (strong, nonatomic) UITextView * instructions;
That FieldView is a property of the viewController
#property (strong, nonatomic) IBOutlet FieldView *fieldView;
When I wanted to hide the UITextView *instructions with code in the viewController, I declared the property in the .h file so that I could eventually do this when a button was pressed
self.fieldView.instructions.hidden = YES;
However, xCode's giving me an error
illegal redeclaration of property in class extension FieldView, attribute must be readwrite while its primary must be readonly
When I added readwrite in both the .h and .m files
#property (weak, nonatomic, readwrite) IBOutlet UITextView *instructions;
it said `perhaps you intended this to be a readwrite redeclaration of a readonly public property
What is the correct way to do what I am trying to do?
To resolve your issue you need declare readonly property in .h file and readwrite property in .m file:
//FieldView.h
#interface FieldView
#property (nonatomic, readonly, strong) UITextView *instructions;
#end
// FieldView.m
#interface FieldView()
#property (nonatomic, readwrite, strong) IBOutlet UITextView *instructions;
#end
I Also got same issue,
If same name property is declared in .h file and you are again declaring it in extension then you will get this error.
So renaming property name will resolve the issue.
For me, I had to remove one of the properties in AppDelegate.h
Before:
#property (nonatomic, strong) UMModuleRegistryAdapter *moduleRegistryAdapter;
#property (nonatomic, strong) UIWindow *window;
After:
#property (nonatomic, strong) UIWindow *window;
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.
I know this could be a duplicated question, but also there are conflicting answers about it ! I'm little confused about that.. my problem is when I profile my app using the instruments to check the leaks .. its keep showing a leak at this method loadNibNamed: .. so related to these questions :
1.Do I need to release IBOutlets when using loadNibNamed: method?
2.Using loadNibNamed leaves a memory leak
I found that some people said that you have to release the IBOutlets even if you don't implement the accessor methods ! and the others says that you shouldn't release these outlets since the iOS will take care about it , so please I need a correct answer based on professoinal experience since that will need me to do alot of work with my project.
Edit / For Example :
If this is my .h class file
#interface MenuViewEPub : UIViewController<ePubBrightnessDelegate,FontDelegate,PagesSlidePreviewerDelegate,ePubExpandSearchBarDelegate,EnviromentAudioChooserDelegate,UIPopoverControllerDelegate,WEPopoverControllerDelegate> {
IBOutlet UIView *upperMenu;
IBOutlet UIView *lowerMenu;
IBOutlet ePubBrightnessButton *brightnessButton;
IBOutlet FontButton *fontButton;
IBOutlet UIBarButtonItem *backButtonTitle;
IBOutlet UIBarButtonItem *indexButtonTitle;
IBOutlet UIBarButtonItem *annotationButtonTitle;
UIView *readerView;
IBOutlet ePubExpandSearchBar *searchBar;
id<MenuViewControllerDelegat>delegate;
IBOutlet PagesSlidePreviewer *pageSilder;
IBOutlet UIButton *arEnButton;
int pageNumber;
int chapterIndex;
int chtCount;
BOOL isLandscape;
UIPopoverController *lastPopover;
}
#property (nonatomic, assign) id<MenuViewControllerDelegat>delegate;
#property (nonatomic, retain) ePubExpandSearchBar *searchBar;
#property (nonatomic, assign) int chtCount;
#property (nonatomic, assign) int pageNumber;
#property (nonatomic, assign) int chapterIndex;
#property (nonatomic, assign) BOOL isRotate;
- (IBAction)tocButtonPressed:(id)sender;
- (IBAction)AnnotationsPressed:(id)sender;
- (IBAction)BackPressed:(id)sender;
- (IBAction)rtfPressed:(id)sender;
- (IBAction) audioPressed:(UIButton*)sender;
- (IBAction) tipsPressed:(UIButton*)sender;
- (void) showMenuInView :(UIView*) destview;
- (void) createViews;
- (void) hideMenu : (BOOL)animate;
- (void) changePageNumber:(int)pageNum;
#end
Do I have to release any outlet except the searchBar ?
Unless you are using ARC, you should release any retained subviews in the viewDidUnload method. This would include subviews that are "injected" via IBOutlets. You would usually also include anything you might have created yourself in the viewDidLoad method.
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