Objective-C - Foundation
--------------------------------------------
Objective-C:
--------------------------------------------
类对象, 类方法(+), 实列方法(-), 工厂方法, 类簇 (NSString)
装箱(boxing), 取消装箱(unboxing)
对象所有权
便利初始化函数(init...), 指定初始化函数 (designated initializer)
man ascii
.m: Objective-C
.mm (.M): Objective-C++
#import <> / "": include once
Function <-> Method (belongs to Class)
%@ = [obj description]
@interface
@implementation
@class
@encode(Type) -> (const char *)
@selector(methodName:) -> (SEL)
- (BOOL) responsesToSelector: (SEL)aSelector
self / super ->
setProperty, property
All Objective-C objects are allocated in heap!!!
Cocoa = Foundation + App Kit
Cocoa Touch = Foundation + UI Kit
--------------------------------------------
NSPredicate (Cocoa):
--------------------------------------------
NSPredicate: NSObject
- (NSPredicate *) predicateWithFormat
- (NSPredicate *) predicateWithSubstitutionVariables: (NSDictionary *)
- (NSPredicate *) predicateWithValue: (BOOL)value
- (BOOL) evaluateWithObject
NSPredicate *p = [NSPredicate predicateWithFormat: @"name == 'Herbie'"];
// or @"name == \"Herbie\""
// @"car.horsepower > 50"
1. By formatter:
%@: 引用字符串, 相当于 'Herbie'
%K: 键路径
// e.g. [NSPredicate predicateWithFormat @"%K == %@", @"name", @"Herbie"];
%d: 数字
2. By variables (变量不能应用于键路径):
$variableName // e.g. @"name == $NAME"
不区分大小写,支持:
AND, OR, NOT, (), &&, ||, !, <>, !=,
BETWEEN {1,10}, IN {'a','b'},
BEGINSWITH[cd], ENDSWITH, CONTAINS, LIKE[cd], MATCHES
ANY, ALL
// BETWEEN / IN %@ / $ARRAYNAME: replace by an array
// BEGINSWITH / ENDSWITH / CONTAINS / LIKE [cd]: c 不区分大小写,d不区分发发音符号
// LIKE: 支持 ?, *
SELF: 可用作键,代表自身
NSArray
-(NSArray *) filteredArrayUsingPredicate
NSMutableArray
-(void) filteredUsingPredicate
--------------------------------------------
KVC(Cocoa):
--------------------------------------------
// Key/Value Coding
@interface NSObject(NSKeyValueCoding)
-(void) setValue: (id)value forKey: (NSString *) key;
-(id) valueForKey: (NSString *)key;
-(void) setValue: (id)value forKeyPath: (NSString *) keyPath;
-(id) valueForKeyPath: (NSString *)keyPath;
// e.g. [car valueForKeyPath: @"tires.pressure"], but @"tires[0].pressure" is wrong
-(void) setValuesForKeysWithDictionary: (NSDictionary *)keyedValues;
-(NSDictionary *) dictionaryWithValuesForKeys: (NSArray *)keys;
// override method
-(void) setValue: (id)value forUndefinedKey: (NSString *)key;
-(id) valueForUndefinedKey: (NSString *)key;
//override method
-(void) setNilValueForKey: (NSString *)key;
@end // NSObject
当没有相应的getter or setter时也能工作 (会直接读取实例变量, "name" or "_name")
读取时(getter), KVC 具有自动包装功能, 能自动把标量值 (int, float, structure等)放入NSNumber或NSValue中返回.
//NSLog(@"%@", [car valueForKey: @"year"]);
设置时(setter), 需要先把标量值包装
// [car setValue: [NSNumber numberWithFloat: 3.14] forKey: @"mileage"]
NSNumber *count = [garage valueForKeyPath @"cars.@count"];
NSNumber *sum = [garage valueForKeyPath @"cars.@sum.mileage"];
NSNumber *avg = [garage valueForKeyPath @"cars.@avg.mileage"];
NSNumber *min = [garage valueForKeyPath @"cars.@min.mileage"];
NSNumber *max = [garage valueForKeyPath @"cars.@max.mileage"];
NSArray *makers = [garage valueForKeyPath @"cars.@distinctUnionOfObjects.make"];
--------------------------------------------
NSCoding:
--------------------------------------------
plist: binary / xml / text
plutil -convert xml1/ binary1 -o fileName
@protocol NSCoding
// 编码与解码 (序列化与反序列化)
-encodeWithCoder: (NSCoder *) aCoder
-initWithCoder: (NSCoder *) aDecoder
[super initWithCoder: decoder]
NSCoder
-encodeObject
-encodeInt
-encodeFloat
-decodeObjectForKey
-decodeIntForKey
-decodeFloatForKey
NSKeyedArchiver: NSCoder
+archivedDataWithRootObject: (id)
NSKeyedUnarchiver: NSCoder
+unarchivedObjectWithData: (NSData *) data
+unarchivedObjectWithFile: (NSString *) path
NSArchiver: NSCoder
NSUnarchiver: NSCoder
-writeToFile
NSArray
NSDictionary
NSData
NSString
NSArray: NSObject
-writeToFile
-arrayWithContentsOfFile
NSDictionary: NSObject
-writeToFile
-dictionaryWithContentsOfFile
NSData: NSObject
-writeToFile
-dataWithContentsOfFile
NSString: NSObject
-writeToFile
-stringWithContentsOfFile
--------------------------------------------
Attributes:
--------------------------------------------
From Objective-C 2.0:
@property (readwrite, readonly, copy, retain, assign, nonatomic) (declaration)
@synthesize (implementation)
@property float newName;
@synthesize newName = name;
obj.pro = val
[obj setPro: val]
var = obj.pro;
var = [obj pro];
self.pro
--------------------------------------------
Category:
--------------------------------------------
Informal Protocol
// 1. no instance variable
// 2. category methods will take priority
@interface NSString (MyNewCategory)
- (void) print;
@end
@implementation NSString (MyNewCategory)
- (void) print { ... }
@end
--------------------------------------------
Protocol:
--------------------------------------------
@protocol NSProtocolName
- (void) requiredMethod1;
@optional (from Objective-C 2.0)
- (void) optionalMethod;
@required (from Objective-C 2.0)
- (void) requiredMethod2;
@end // @protocol
@interface MyClass : NSObject
@end
- (void) setObjectValue: (id ) obj;
copy -> copyWithZone (defined in )
[[[self class] allocWithZone: zone] init] -> so all derived class will work correctly
--------------------------------------------
Memory & Init:
--------------------------------------------
alloc / new / copy <-> release / autorelease
[Class new] == [[Class alloc] init] (recommended)
- (id) init
{
if (self = [super init])
{ ... }
return (self);
}
NSAutoreleasePool
[[NSAutoreleasePool alloc] init]
-release
-drain (>=10.4)
// could new more than one NSAutoreleasePool, they store as Stack, autorelease will put the object into the top NSAutoreleasePool in the Stack.
// after a loop it will release
Garbage Collection
// Info | Build | GCC 4.2 - Code Generation | Objective-C Garbage Collection
// set obj = nil asap
// after a loop, it will trigger
// for iPhone, GC is disabled, and avoid using autorelease or some return autorelease object helper methods/functions
self.name = nil (use setter to release "name")
--------------------------------------------
Xcode:
--------------------------------------------
esc or ctl+,
ctl+.
ctl+/ or tab
double click ( ) { } [ ]
^FBNP
^AE
^T
^DK
^L
Context | Edit in All Scope
Context | Refactor...
File | Open Quickly
View | Zoom Editor In/Out (Cmd+Shift+E)
View | Switch to Header|Source File(^Cmd+Up)
View | Code Folding
Edit | Add to Bookmarks (Cmd+D)
//???: name
//!!!: name
//TODO: name
//FIXME: name
//MARK: name
#pragma mark name
#pragma mark -
--------------------------------------------
Application Kit:
--------------------------------------------
#import
@interface AppController: NSObject{
IBOutlet NSTextField *name;
}
- (IBAction) lowercase: (id) sender;
@end
// 1. nib will create all objects by [[ClassName alloc] init]
// 2. link
// 3. send message "awakeFromNil" to all objects
NSTextField
-stringValue
-setStringValue
--------------------------------------------
Foundation:
--------------------------------------------
NSObject
+alloc (retainCount = 1) // zero initialization
-init
+new(retainCount = 1)
-copy (retainCount = 1)
+allocWithZone
-(id)retain (retainCount ++)
-retainCount,
-release (retainCount--)
-(id)autorelease (put into NSAutoreleasePool)
-dealloc (if retainCount == 0)
-finalize (>=10.4) // called before object is destructed
+class
+superclass
-(id)mutableCopy
// some other factory methods will automatically "autorelease" object
NSString *str = @"string"
+stringWithFormat
-initWithFormat
-initWithContentsOfFile
-length
-isEqualTo
-isEqualToString
-compare
-hasPrefix
-hasSuffix
-rangeOfString
-componentsSeparatedByString
-stringByExpandingTildeInPath
-fileExtension
-uppercaseString
-lowercaseString
NSMutableString
+stringWithCapacity
-appendString
-appendFormat
-deleteCharactersInRange
NSArray (no nil element, but [NSNull null], Objective-C object element only)
+array
+arrayWithObjects (ends with nil)
+arrayWithContentsOfFile
-count
-objectAtIndex
-componentsJoinedByString
-objectEnumerator
-reverseObjectEnumerator
// when copy is shallow copy
// when array release, it also release its elements
NSMutableArray
+arrayWithCapacity
-addObject
-removeObjectAtIndex
-replaceObjectAtIndex //will release old object and retain new object
NSEnumerator
-nextObject
for(... in array) { }
for(... in enumerator) { }
NSDictionary (no nil element, but [NSNull null], Objective-C object element only)
+dictionaryWithObjectsAndKeys (ends with nil)
+dictionary
-objectForKey
NSMutableDictionary
+dictionaryWithCapacity
-setObject
-removeObjectForKey
NSNumber : NSValue
+numberWithChar
+numberWithInt
+numberWithFloat
+numberWithBool
-charValue
-intValue
-floatValue
-stringValue
NSValue
+valueWithBytes
+valueWithRect
+valueWithPoint
+valueWithSize
+valueWithRange
-getValue
-rectValue
-pointValue
-sizeValue
-rangeValue
NSNull
+null
NSFileManager
+defaultManager
-enumeratorAtPath
NSDate
+date
-dateWithTimeIntervalSinceNow
NSData
-length
-bytes
NSMutableData
NSNotFound
NSRange r = NSMakeRange();
NSPoint p = NSMakePoint();
NSSize s = NSMakeSize();
NSRect r = NSMakeRect();
--------------------------------------------