mirror of
https://github.com/wnagrodzki/CocoaProgrammingGuidelines.git
synced 2025-05-06 19:11:47 +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}
|
\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}
|
\end{document}
|
||||||
|
|
Loading…
Add table
Reference in a new issue