object property in objective-c - objective-c

#interface Category : NSObject
#property(nonatomic) NSInteger ID;
#property(nonatomic, retain) NSString *Name;
#property(nonatomic, retain) NSString *Description;
#end
product class
#interface Product : NSObject
#property(nonatomic) NSInteger ID;
#property(nonatomic, retain) NSString *Name;
#property(nonatomic, retain) NSString *Description;
#property(nonatomic, retain) Category *category;
#end
How do I create a property of type Category. Is it possible at all?

You do it just like you have, except you need to add a forward declaration of your Category class in Product.h (before your #interface line):
#Class Category;
And then import the header in Product.m
#import "Category.h"

1) If you class Product is defined in separate file, then:
#import "Category.h" // file, where class Category is defined
#interface Product : NSObject
#property(nonatomic) NSInteger ID;
#property(nonatomic, retain) NSString *Name;
#property(nonatomic, retain) NSString *Description;
#property(nonatomic, retain) Category *category;
#end
2) If your classes Product and Category are defined in same file then you don't need any additional import but be sure that class Categiry is defineed earlier then Product.
3) In the case when two classes have objects of type of each other then your should use #class tag:
#class Product;
#interface Category : NSObject
#property(nonatomic, retain) Product *product;
#end
#interface Product : NSObject
#property(nonatomic, retain) Category *category;
#end

Yes, it is possible, and the syntax that you have posted is correct. If you are having a problem, perhaps it may be because you need to do
#import "Category.h"
at the top of Product.h, and you will need to make sure to #synthesize category. But since you have been using other properties, I assume you knew that already.

Related

Why declare the variables of public properties on the interface with the property declarations?

I'm looking at this code below and trying to figure out which of the two of us... (me, or the person who wrote it) doesn't know what they're doing.
Why did he/she declare properties, then declare matching variables as well?
I can't ask the person because this project is inherited from a group long gone.
#interface LayerList : UIViewController <UITableViewDataSource, UITableViewDelegate>
{
UITableView *tvList;
ArcGisViewController *mapController;
NSArray *fileList;
}
#property (nonatomic, strong) IBOutlet UITableView *tvList;
#property (nonatomic, strong) ArcGisViewController *mapController;
#property (nonatomic, strong) NSArray *fileList;
-(void)visibleSwitchValueChanged:(id)sender;
-(IBAction) Cancel;
#end
This was the usual way in a day when you had to synthesize the properties manually before auto-synthesizing was introduced.

Why the code does not work to avoid Circular References?

I am compiling code to avoid Retain Cycle, When I use weak , I got this error: 1. property of weak attribute must be of object type; 2. Unknown type name 'OrderEntry'. What is wrong with the code? Thanks!
// OrderEntry.h
#import <Foundation/Foundation.h>
#import "OrderItem.h"
#import "Address.h"
#interface OrderEntry : NSObject
#property (strong, nonatomic)OrderItem *orderItem;
#property (strong, nonatomic)Address *shippingAddress;
#property (strong, nonatomic) NSString *orderID;
#end
// OrderItem.h
#import <Foundation/Foundation.h>
#import "OrderEntry.h"
#interface OrderItem : NSObject
#property (strong,nonatomic) NSString *name;
#property (weak, nonatomic) OrderEntry *entry;
#end
The problem is with both .h files each including the other. This causes a circular dependency on the declarations. The simple solution is to use forward declarations instead.
OrderEntry.h:
#import <Foundation/Foundation.h>
#import "Address.h"
#class OrderItem;
#interface OrderEntry : NSObject
#property (strong, nonatomic) OrderItem *orderItem;
#property (strong, nonatomic) Address *shippingAddress;
#property (strong, nonatomic) NSString *orderID;
#end
OrderItem.h:
#import <Foundation/Foundation.h>
#class OrderEntry;
#interface OrderItem : NSObject
#property (strong, nonatomic) NSString *name;
#property (weak, nonatomic) OrderEntry *entry;
#end
Then you import the .h files in the .m file.
The general guideline is to import the fewest possible .h files in another .h file. Use forward declarations for classes and protocols whenever possible.

Property requires method to be defined in NSManagedObject subclass

I have some protocol like this:
#protocol UserProtocol <NSObject>
#property (nonatomic, strong) NSNumber *uid;
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSNumber *rating;
#end
Then I created some actual class that implements that:
#interface User : NSObject <UserProtocol>
#end
Now I need another implementation that uses CoreData so I created CDUser entity (Xcode also generates category for that):
// CDUser.h
#interface CDUser : NSManagedObject <UserProtocol>
#end
// CDUser+CoreDataProperties.h
#interface CDUser (CoreDataProperties)
#property (nullable, nonatomic, retain) NSNumber *uid;
#property (nullable, nonatomic, retain) NSString *name;
#property (nullable, nonatomic, retain) NSNumber *rating;
#end
// CDUser+CoreDataProperties.m
#implementation CDUser (CoreDataProperties)
#dynamic uid;
#dynamic name;
#dynamic rating;
#end
CDUser actually implements UserProtocol but I have warnings like so for all properties:
Property 'uid' requires method 'uid' to be defined - use #synthesize, #dynamic or provide a method implementation in this class implementation
If I add #dynamic uid; again in CDBook.m then I get the following error:
Property declared in category 'CoreDataProperties' cannot be implemented in class implementation
How can I solve these warnings in a proper way?
Cause CDUser doesn't implement this protocol. Use protocol on category instead.
#interface CDUser : NSManagedObject
#end
// CDUser+CoreDataProperties.h
#interface CDUser (CoreDataProperties) <UserProtocol>
#property (nullable, nonatomic, retain) NSNumber *uid;
#property (nullable, nonatomic, retain) NSString *name;
#property (nullable, nonatomic, retain) NSNumber *rating;
#end

How to silent warning incompatible property type

I am using RTSPagedView from github in my project. Which gives me this warning
Property type 'id<RTSPagedViewDelegate>' is incompatible with type 'id<UIScrollViewDelegate>' unherited from 'UIScrollView'
in
#property (nonatomic, assign) IBOutlet id <RTSPagedViewDelegate> delegate;
in RTSPagedView.h
App is working fine with this warning. Anyone came across this before or knows the solution please help.
Link for this is RTSPagedView
// RTSPagedView.h
// PagedView
// http://github.com/rplasman/RTSPagedView
#import <UIKit/UIKit.h>
#protocol RTSPagedViewDelegate;
#interface RTSPagedView : UIScrollView
#property (nonatomic, assign) IBOutlet id <RTSPagedViewDelegate> delegate;
#property (nonatomic, assign) NSUInteger currentPage;
#property (nonatomic, readonly) NSUInteger numberOfPages;
#property (nonatomic, assign) BOOL continuous;
- (void)resizeBounds:(CGRect)bounds;
- (UIView *)dequeueReusableViewWithTag:(NSInteger)tag;
- (UIView *)viewForPageAtIndex:(NSUInteger)index;
- (void)scrollToPageAtIndex:(NSUInteger)index animated:(BOOL)animated;
- (void)reloadData;
- (NSUInteger)indexForView:(UIView *)view;
#end
#protocol RTSPagedViewDelegate <UIScrollViewDelegate>
- (NSUInteger)numberOfPagesInPagedView:(RTSPagedView *)pagedView;
- (UIView *)pagedView:(RTSPagedView *)pagedView viewForPageAtIndex:(NSUInteger)index;
#optional
- (void)pagedView:(RTSPagedView *)pagedView didScrollToPageAtIndex:(NSUInteger)index;
- (void)pagedView:(RTSPagedView *)pagedView didRecycleView:(UIView *)view;
#end
Try it this way:
#property (nonatomic, assign) IBOutlet id <UIScrollViewDelegate, RTSPagedViewDelegate> delegate;
Works for me.
Issue occurred because
#property (nonatomic, assign) IBOutlet id <RTSPagedViewDelegate> delegate;
In this delagate is poniting towards UIScrollViewDelagate because RTSPagedView is inherited from UIScrollView.
Modify the complete delegate name with any other name like
#property (nonatomic, assign) IBOutlet id <RTSPagedViewDelegate> rtspDelegate;
It will remove the warning.
I think (I cannot be sure without more code) that you are haven't declared your delegate class as conforming to the RTSPagedViewDelegate protocol.
try this:
YourClass.h:
#interface YourClass : NSObject <UIScrollViewDelegate, RTSPagedViewDelegate>
...
#end
And now when you do:
rtsPageView.delegate = self;
The warning should be gone.
This could be complete rubbish, in which case I'll delete it.

Why am I getting unsafe retained?

I've just starting out with obj-c and I created 2 files, a .h and a .m file. The .h file is..
#import <Foundation/Foundation.h>
#interface CardUnit : NSObject
{
#private
NSString *_name;
NSString *_gold;
}
#property (nonatomic, assign) NSString *name;
#property (nonatomic, assign) NSString *gold;
#end
and the .m file is
#import "CardUnit.h"
#implementation CardUnit
#synthesize gold = _gold;
#synthesize name = _name;
#end
But it's giving me 2 errors on the #synthesize lines, which are...
"Existing ivar "_gold" for property gold with assign attribute must be __unsafe retained" and the same for name.
From the error i see you are using ARC, Automatic Reference Counting .
Basically you can get rid of all the #synthesize statements and even the private declarations of the ivar's name and gold is not necessary.
All you need is the CardUnit.h to be like this :
#interface CardUnit : NSObject
#property (assign) NSString *name;
#property (assign) NSString *gold;
#end
The Xcode compiler will take care of the rest.
See also this reply on SO