ZGCPerson.h
[code]//
// ZGCPerson.h
// ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties
//
// Created by EvilKernel on 9/30/14.
// Copyright © 2014 Zerogravity. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface ZGCPerson : NSObject
// Using properties. Properties are a shorthand for automatically declaring and implementing accessor methods. it simplifies code by making declarations and implementations ‘implicit’.
@property (nonatomic) float heightInMeters;
@property (nonatomic) int weightInKilos;
// only declaring this method explicitely for calculating BMI. Setter/getter accessors
// for remaining ones automatically taken care of by ‘@property’ shorthand.
// BMIPerson will have a method to calculate the Body Mass Index
- (float)bodyMassIndex;
@end
[/code]
ZGCPerson.m
[code]//
//
// ZGCPerson.m
// ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties
//
// Created by EvilKernel on 9/30/14.
// Copyright © 2014 Zerogravity. All rights reserved.
//
#import “ZGCPerson.h”
@implementation ZGCPerson
-
(float)bodyMassIndex
{
// Using “self” (implicit local variable). self is a pointer to the object that is running the method.
// many devs are regliious about never reading/writing to an instance variable directly.float h = [self heightInMeters];
return [self weightInKilos] / (h * h);
}
@end
[/code]
ZGCEmployee.h
[code]//
// ZGCEmployee.h
// ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties
//
// Created by EvilKernel on 9/30/14.
// Copyright © 2014 Zerogravity. All rights reserved.
//
#import “ZGCPerson.h”
@class ZGCAsset; // @class can be used with header files instead of import as it does not need all of the info #import provides, just enough to read declarations. it is faster for this purpose.
@interface ZGCEmployee : ZGCPerson // ZGCEmployee is a subclass of ZGCPerson (my original class)
{
NSMutableArray *_assets;
}
//some properties for employee object
// properties will automatically create _instanceVariables as well as synthetize setter and getter methods for you
// both on primitive types declarations as well as objects type declarations, like NSDate, NSString, etc (typedefs as they are called)
@property (nonatomic) unsigned int employeeID;
@property (nonatomic) unsigned int officeAlarmCode;
@property (nonatomic) NSDate *hireDate; // points to an object
@property (nonatomic, copy) NSArray *assets; //point to an object
// method for calculating years of employment
- (double)yearsOfEmployment;
// method to add asset objects to an array
- (void)addAsset:(ZGCAsset *)a;
// method to remove asset from an array
- (void)removeAsset:(NSUInteger)i;
// method for calculating value of assets
- (unsigned int)valueOfAssets;
@end
[/code]
ZGCEmployee.m
[code]//
// ZGCEmployee.m
// ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties
//
// Created by EvilKernel on 9/30/14.
// Copyright © 2014 Zerogravity. All rights reserved.
//
#import “ZGCEmployee.h”
#import “ZGCAsset.h” //using import in this case - @class is not sufficuent as more is needed to know.
@implementation ZGCEmployee
- (double)yearsOfEmployment
{
// Do I have a nil hireDate?
if (self.hireDate) {
//NSTimeInterval is the same as double typedef
NSDate *now = [NSDate date];
NSTimeInterval secs = [now timeIntervalSinceDate:self.hireDate];
return secs / 31557600.0; //seconds per year
}else{
return 0;
}
}
/* you can override an inherited method in a subclass by writing
a new implementation (original declaration must remain the same) */
- (float)bodyMassIndex
{
// return 19.0; //overrides output to fixed BMI for instance
/* when overriding a method, a subclass can also build on the original
implementation of the Superclass rather than replacing it whole. In this
case we are discounting 10% off their BMI as calculated by the original
implementation */
float normalBMI = [super bodyMassIndex]; //instruct to use method at superclass
return normalBMI * 0.9;
}
// acceessors for asset properties
/* here I override the synthetized property method/accessor for 'assets’
for a setter which sets ‘assets’ to a mutable version of NSArray */
- (void)setAssets:(NSArray *)a
{
_assets = [a mutableCopy]; // means: assets = an [empty] mutable array
}
//again, overriding synthetized property method
// to return copied version of NSArray above (which is a mutable version)
-
(NSArray *)assets
{
return [_assets copy];
} -
(void)addAsset:(ZGCAsset *)a
{
// Is assets nil?
if (!_assets) {
// create the array
_assets = [[NSMutableArray alloc] init];}
[_assets addObject:a]; //adds an asset object to the mutable array
} -
(void)removeAsset:(NSUInteger)i //removes asset at supplied index
{
[_assets removeObjectAtIndex:i];
} -
(unsigned int)valueOfAssets
{
// sum up the resale value of assets
unsigned int sum = 0;
for (ZGCAsset *a in _assets) { // must count each asset in array as each employee object owns one array of assets, as per main()
sum += [a resaleValue];
}
return sum;
}
// overriding description method for illustration purposes to track dealloaction
- (NSString *)description
{
return [NSString stringWithFormat:@"<Employee %u: $%u in assets>", self.employeeID, self.valueOfAssets];
}
// overriding dealloc method to illustrate deallocation (will not actually dealloc like this
- (void)dealloc
{
NSLog(@“deallocating %@”, self);
}
@end
[/code]
ZGCAsset.h
[code]//
// ZGCAsset.h
// ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties
//
// Created by EvilKernel on 10/3/14.
// Copyright © 2014 Zerogravity. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface ZGCAsset : NSObject
//properties for asset object
@property (nonatomic, copy) NSString *label;
@property (nonatomic) unsigned int resaleValue;
@end
[/code]
ZGCAsset.m
[code]//
// ZGCAsset.m
// ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties
//
// Created by EvilKernel on 10/3/14.
// Copyright © 2014 Zerogravity. All rights reserved.
//
#import “ZGCAsset.h”
@implementation ZGCAsset
// overriding description method for illustration purposes to track dealloaction - this overrides what %@ returns for the object.
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: $%u>", self.label, self.resaleValue];
}
// override dealloc method to illustrate
// how ARC deallocaction activity (will not actually dealloc this way, just log)
- (void)dealloc
{
NSLog(@“deallocating %@”, self);
}
@end
[/code]
main.m
[code]//
// main.m
// ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties
//
// Created by EvilKernel on 9/29/14.
// Copyright © 2014 Zerogravity. All rights reserved.
//
#import <Foundation/Foundation.h> //angled brackets tells the compiler that Foundation.h is a precompiled header found in the apple libs
// #import “ZGCPerson.h” //importing my first class - ZGCPerson. The quotation marks tell compiler to look for header within current project
#import “ZGCEmployee.h” //importing subclass header only - superclass header already imported in subclass’s header
#import “ZGCAsset.h” // importing header for asset class.
int main(int argc, const char * argv[])
{
@autoreleasepool {
// Create an array of 10 ZGCEmployee objects
NSMutableArray *employees = [[NSMutableArray alloc] init];
for (int i = 0; i < 10; i++) {
ZGCEmployee *myEmployee = [[ZGCEmployee alloc] init];
// Give the instance variables interesting values
myEmployee.weightInKilos = 90 + i;
myEmployee.heightInMeters = 1.8 - i/10.0;
myEmployee.employeeID = i;
myEmployee.hireDate = [NSDate dateWithNaturalLanguageString:@"January 6th, 2003"];
// Put the employees in the employee array
[employees addObject:myEmployee];
}
// Create 10 assets objects
for (int i = 0; i < 10; i++) {
ZGCAsset *asset = [[ZGCAsset alloc] init];
// Give them interesting labels and resale values
NSString *currentLabel = [NSString stringWithFormat:@"Laptop %d", i];
asset.label = currentLabel;
asset.resaleValue = 350 + i * 17;
// Get a random number (employee) between 0 and 9 inclusive (based on array count)
NSUInteger randomIndex = random() % [employees count];
// Find that employee
ZGCEmployee *randomEmployee = [employees objectAtIndex:randomIndex]; //avioding subscripting / easy toread
//Assign the asset to the employee
[randomEmployee addAsset:asset]; // this method creates a mutable array (_assets) if it doesnt exist and adds asset to it - each employee object gets an array object of assets.
}
NSLog(@"Employees: %@", employees); // uses overwritten description method in zgemployee.m
sleep(3);
NSLog(@"------Giving up ownership of one employee------");
[employees removeObjectAtIndex:5]; // invokes ovewritten dealloc() method in the class for illustration.
sleep(3);
NSLog(@"------Removing an asset from a random employee------");
// Get a random number employee from what is left in the employee array
NSUInteger randomIndex = random() % [employees count];
ZGCEmployee *randomEmployee = [employees objectAtIndex:randomIndex];
// iterate up to # of remaining assets to avoid NSException.
for (int i = 0; i < [randomEmployee.assets count]; i++) {
[randomEmployee removeAsset:i]; // method to remove an asset
}
sleep(3);
NSLog(@"------Giving up ownership of arrays------");
employees = nil; // invokes overwritten dealloc() method in the class object for illustration
sleep(3);
}
return 0;
}
[/code]
[color=#4000FF]****** OUTPUT *******
2014-10-21 01:48:09.652 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] Employees: (
"<Employee 0: $0 in assets>",
"<Employee 1: $503 in assets>",
"<Employee 2: $469 in assets>",
"<Employee 3: $768 in assets>",
"<Employee 4: $0 in assets>",
"<Employee 5: $836 in assets>",
"<Employee 6: $819 in assets>",
"<Employee 7: $384 in assets>",
"<Employee 8: $0 in assets>",
"<Employee 9: $486 in assets>"
)
2014-10-21 01:48:12.656 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] ------Giving up ownership of one employee------
2014-10-21 01:48:12.656 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Employee 5: $836 in assets>
2014-10-21 01:48:12.656 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Laptop 3: $401>
2014-10-21 01:48:12.657 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Laptop 5: $435>
2014-10-21 01:48:15.659 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] ------Removing an asset from a random employee------
2014-10-21 01:48:15.660 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Laptop 1: $367>
2014-10-21 01:48:18.665 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] ------Giving up ownership of arrays------
2014-10-21 01:48:18.665 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Employee 0: $0 in assets>
2014-10-21 01:48:18.665 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Employee 1: $503 in assets>
2014-10-21 01:48:18.665 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Laptop 9: $503>
2014-10-21 01:48:18.665 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Employee 2: $469 in assets>
2014-10-21 01:48:18.665 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Laptop 7: $469>
2014-10-21 01:48:18.666 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Employee 3: $768 in assets>
2014-10-21 01:48:18.666 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Laptop 0: $350>
2014-10-21 01:48:18.666 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Laptop 4: $418>
2014-10-21 01:48:18.666 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Employee 4: $0 in assets>
2014-10-21 01:48:18.666 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Employee 7: $384 in assets>
2014-10-21 01:48:18.666 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Laptop 2: $384>
2014-10-21 01:48:18.667 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Employee 8: $0 in assets>
2014-10-21 01:48:18.667 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Employee 9: $486 in assets>
2014-10-21 01:48:18.667 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Laptop 8: $486>
2014-10-21 01:48:21.670 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Employee 6: $452 in assets>
2014-10-21 01:48:21.670 ObjC_MyFirst_CLASS_ZGCPerson_time_using_Properties[41868:5351905] deallocating <Laptop 6: $452>
Program ended with exit code: 0[/color]