mirror of
https://github.com/wnagrodzki/CocoaProgrammingGuidelines.git
synced 2025-05-03 17:41:51 +02:00
Cora Data. Category provides helper methods to managed object. Custom objects are stored as transformable attributes. Objective-C types are stored through NSValue.
This commit is contained in:
parent
5b4c7f9adf
commit
ef95e15f1b
2 changed files with 129 additions and 0 deletions
Binary file not shown.
|
@ -949,4 +949,133 @@ The following getter implementation traverses view controller hierarchy, and ret
|
|||
\end{codelisting}
|
||||
|
||||
|
||||
\section{Core Data}
|
||||
|
||||
|
||||
\begin{importantlisting}
|
||||
NSManagedObject's properties must not be prefixed with "new". Due to @dynamic compiler directive, the following compiler error is suppressed: "property's synthesized getter follows Cocoa naming convention for returning 'owned' objects".
|
||||
\end{importantlisting}
|
||||
|
||||
|
||||
\subsection{Category provides helper methods to managed object}
|
||||
|
||||
NSManagedObject subclasses can be generated by Xcode schema editor automatically.
|
||||
|
||||
\begin{codelisting}
|
||||
@interface Person : NSManagedObject
|
||||
|
||||
@property (nonatomic, retain) NSString * name;
|
||||
@property (nonatomic, retain) NSString * surname;
|
||||
|
||||
@end
|
||||
\end{codelisting}
|
||||
|
||||
Therefore, all helper methods are kept in a category in a separate file, otherwise they would be overridden by the editor.
|
||||
|
||||
\begin{codelisting}
|
||||
@interface Person (Additions)
|
||||
|
||||
- (NSString *)fullName;
|
||||
|
||||
@end
|
||||
\end{codelisting}
|
||||
|
||||
\subsection{Custom objects are stored as transformable attributes}
|
||||
|
||||
A custom object can be stored by Core Data as a transformable attribute, if it conforms to NSCoding protocol. Xcode schema editor uses id for this attributes, which deprives developer of good type checking.
|
||||
|
||||
\begin{codelisting}
|
||||
@interface Person : NSManagedObject
|
||||
|
||||
@property (nonatomic, retain) id eyeColorTransformableType;
|
||||
|
||||
@end
|
||||
\end{codelisting}
|
||||
|
||||
To ameliorate the situation, a property with the proper class type is provided by a category.
|
||||
|
||||
\begin{codelisting}
|
||||
@interface Person (Additions)
|
||||
|
||||
@property (strong, nonatomic) UIColor * eyeColor;
|
||||
|
||||
@end
|
||||
\end{codelisting}
|
||||
|
||||
Consequently the original property is never used except by the shadowing property's accessors.
|
||||
|
||||
\begin{codelisting}
|
||||
@implementation Person (Additions)
|
||||
|
||||
- (void)setEyeColor:(UIColor *)eyeColor
|
||||
{
|
||||
self.eyeColorTransformableType = eyeColor;
|
||||
}
|
||||
|
||||
- (UIColor *)eyeColor
|
||||
{
|
||||
return self.eyeColorTransformableType;
|
||||
}
|
||||
|
||||
@end
|
||||
\end{codelisting}
|
||||
|
||||
|
||||
\subsection{Objective-C types are stored through NSValue}
|
||||
|
||||
NSValue is a simple container for Objective-C data types. It conforms to NSCoding protocol, thus can be stored by Core Data as transformable attribute.
|
||||
|
||||
\begin{codelisting}
|
||||
@interface Figure : NSManagedObject
|
||||
|
||||
@property (nonatomic, retain) id imaginaryPositionTransformableType; // stores NSValue object
|
||||
|
||||
@end
|
||||
\end{codelisting}
|
||||
|
||||
A category provides a shadowing property for the convenience.
|
||||
|
||||
\begin{codelisting}
|
||||
struct ComplexNumber {
|
||||
float real;
|
||||
float imaginary;
|
||||
};
|
||||
typedef struct ComplexNumber ComplexNumber;
|
||||
|
||||
extern ComplexNumber const ComplexNumberZero;
|
||||
|
||||
|
||||
@interface Figure (Additions)
|
||||
|
||||
@property (assign, nonatomic) ComplexNumber imaginaryPosition;
|
||||
|
||||
@end
|
||||
\end{codelisting}
|
||||
|
||||
The getter initializes the local variable so it does not return uninitialized value, if the shadowed property is nil.
|
||||
|
||||
\begin{codelisting}
|
||||
@implementation Figure (Additions)
|
||||
|
||||
- (ComplexNumber)imaginaryPosition
|
||||
{
|
||||
ComplexNumber imaginaryPosition = ComplexNumberZero;
|
||||
[self.imaginaryPositionTransformableType getValue:&imaginaryPosition];
|
||||
return imaginaryPosition;
|
||||
}
|
||||
\end{codelisting}
|
||||
|
||||
The setter creates NSValue object with the passed value, and stores it.
|
||||
|
||||
\begin{codelisting}
|
||||
- (void)setImaginaryPosition:(ComplexNumber)imaginaryPosition
|
||||
{
|
||||
NSValue * value = [NSValue valueWithBytes:&imaginaryPosition objCType:@encode(ComplexNumber)];
|
||||
self.imaginaryPositionTransformableType = value;
|
||||
}
|
||||
|
||||
@end
|
||||
\end{codelisting}
|
||||
|
||||
|
||||
\end{document}
|
||||
|
|
Loading…
Add table
Reference in a new issue