Sean's Note: Objective-C
顯示具有 Objective-C 標籤的文章。 顯示所有文章
顯示具有 Objective-C 標籤的文章。 顯示所有文章

2015年2月11日 星期三

[讀書筆記] Effective Objective-C - Chapter4

4. Protocols and Categories

Item 23: Use Delegate and Data Source Protocols for Interobject Communication 

  1. A delegate property will always be defined using the weak attribute.
  2. If required, implement the bitfield structure approach to cache which methods a delegate responds to from the protocol. 

Item 24: Use Categories to Break Class Implementation into Manageable Segments

  1. Use categories to split a class implementation into more manageable fragments.
  2. Create a category called Private to hide implementation detail of methods that should be considered as private.

Item 25: Always Prefix Category Names on Third-Party Classes

Item 26: Avoid Properties in Categories

  1. Can use associated objects instead, but not good enough.

Item 27: Use the Class-Continuation Category to Hide Implementation Detail

Item 28: Use a Protocol to Provide Anonymous Objects 

2015年2月10日 星期二

[讀書筆記] Effective Objective-C - Chapter3

3. Interface and API Design

Item 15: Use Prefix Names to Avoid Namespace Clashes

  1. Choose a class prefix that befits your company, application, or both. Then stick with that prefix throughout.
  2. If you use a third-party library as a dependency of your own library, consider prefixing its names with your prefix. 

Item 16: Have a Designated Initializer

  1. Throw an exception in initializers overridden from superclasses that should not be used in the subclass. 

Item 17: Implement the description Method

  1. -(NSString*)description,   -(NSString*)debugDescription

Item 18: Prefer Immutable Objects

Item 19: Use Clear and Consistent Naming

  1. Verbose but clear naming of methods is more acceptable in Objective-C than in other languages.
  2. Avoid abbreviations, such as str, and instead use full names, such as string.

Item 20: Prefix Private Method Names

  1. Suggestion: Use "p_" as prefix for private methods.
  2. Avoid using single "_" as the method prefix, since this is reserved by Apple.

Item 21: Understand the Objective-C Error Model

  1. Any objects that should be released at the end of a scope in which an exception is thrown will not be released. (-fobjc-arc-exceptions)

Item 22: Understand the NSCopying Protocol

  1. To support copying: 
    1. Implement NSCopying protocol. 
    2. Override -(id)copyWithZone:(NSZone*)zone or -(id)mutableCopyWithZone:(NSZone*)zone 
  2. If your object has mutable and immutable variants, implement both the NSCopying and NSMutableCopying protocols.

2014年12月22日 星期一

[讀書筆記] Effective Objective-C - Chapter 2

2. Objects, Messaging, and the Runtime

Item 6: Understand Properties

  1. Four categories of attributes can be applied: 
    1. Atomicity: atomic(default)/nonatomic
    2. Read/Write: readwrite/readonly
    3. Memory-Management Semantics: assign, strong, weak, unsafe_unretained, copy
    4. Methods Names: getter=<name>, setter=<name>
  2. If you implement your own accessors, you should make them adhere to specified attributes yourself.
  3. Never use use your own accessors in an init(or dealloc) method.
  4. All properties are declared nonatomic on iOS because the locking introduces such an overhead on iOS, and it doesn't ensure thread safety.

Item 7: Access Instance Variables Primarily Directly When Accessing Them Internally

  1. Prefer to read data directly through instance variables internally and to write data through properties internally. 
Additional Study: Should I Use a Property or an Instance Variable?

Item 8: Understand Object Equality

  1. Use isEqualToString: is faster than calling isEqual:.
  2. Objects that are equal must have the same hash, but objects that have the same hash do not necessarily have to be equal.
  3. Be aware of what can happen when you mutate on object that's in a collection.

Item 9: Use the Class Cluster Pattern to Hide Implementation Detail

  1. Factory pattern is one way of creating a class cluster.
  2. There is no abstract base class for Objective-C. Instead, convention foe how to use a class should be made in documentation.
  3. Most of collection classes are class clusters, such as NSArray and NSMutableArray.
  4. Should use isKindOfClass: rather than class when comparing class cluster.

Item 10: Use Associated Objects to Attach Custom Data to Existing Classes

  1. objc_setAssociatedObject, objc_getAssociatedObject
  2. The accessing of associated objects is functionally similar to imaging that the object is an NSDictionary. An import difference is that key is treated purely as an opaque pointer. Thus, it's common to use static global variables for the keys.
  3. Can be used on delegate protocol methods.
  4. Can easily introduce hard-to-find bugs. 

Item 11: Understand the Role of objc_msgSend
  1. void objc_msgSend(id self, SEL cmd, ...)
  2. The function loos through the list of methods implemented by the receiver's class. It caches the result in a fast map, one for each class.

Item 12: Understand Message Forwarding

  1. It's not compile-time error to send a message to a class that it doesn't understand, since methods can be added to classes at runtime. When it receives a method that it doesn't understand, an object goes through message forwarding.
  2. The forwarding pathways are split into two avenues:
    Dynamic Method Resolution
    +(BOOL)resolveInstanceMethod:(SEL)selector
    +(BOOL)resolveClassMethod:(SEL)selector

    Replacement Receiver
    -(id)forwardingTargetForSelector:(SEL)selector
    Full Forwarding Mechanism
    -(void)forwardInvocation:(NSInvocation*)invocaiton

Item 13: Consider Method Swizzling to Debug Opaque Methods

  1. Swizzling is the process of swapping one method implementation for another, usually to add functionality to the original implementation. 
  2. class_getInstanceMethod, method_exchangeImplementaitons
  3. Useful for debugging.

Item 14: Understand What a Class Object Is

  1. Always prefer introspection methods were possible, rather than direct comparison of class objects, since the object may implement message forwarding.

 

2014年12月11日 星期四

[讀書筆記] Effective Objective-C - Chapter1

1. Accustoming Yourself to Objective-C

Item 1: Familiarize Yourself with Objective-C's Roots

  1. It uses messaging structure with dynamic binding rather than function calling.
  2. Memory for objects is always allocated in heap space and never on the stack.
  3. Some variables like CGRect not holding Objective-C objects are using stack space.

Item 2: Minimize Importing Headers in Headers

  1. Use forward declaration to decrease compile time. EX: @class EOCEmployer;
  2. Using forward declaration also alleviates the problem of both classes referring to each other.

Item 3: Prefer Literal Syntax over the Equivalent Methods

  • Literal Arrays
    NSArray *arrayA = [NSArray arrayWithObjects:object1, object2, object3, nil];NSArray *arrayB = @[object1, object2, object3];
    If object2 is nil, the literal array, array B, will cause the exception to be thrown, However, arrayA will still be created but will contain only object1.
  • Literal Arrays
    Similar to above.
  • Limitations
    If a mutable variant is required, a mutable copy must be taken.
    EX: NSMutableArray *mutable = [@[@1, @2, @3, @4, @5] mutableCopy]; 

Item 4: Prefer Typed Constants to Preprocessor #define

  1. Type constants have type information(More readable).
  2. The usual convention for constants is to prefix with the letter k for constants that are local to a translation unit. For constants that are exposed outside of a class, it's usual to prefix with the class name.

Item 5: Use Enumerations for States, Options, and Status Codes

  1. C++11 brought some changes like the capability to dictate the underlying type used to store variables of the enumerated type.

2014年11月14日 星期五

Class Extensions Extend the Internal Implementation

常會看到在 .h 和 .m 檔裡都有 @interface 的敘述,一開始覺得很納悶,@interface
不是只要寫在 .h 就好了嗎?不過仔細看又略有不同,在 .m 的 @interface 敘述後面還多了
小括號 ()。

// Classname.m

@interface Classname() {
    id _instanceVar;
}

@property NSObject *extraProperty;

@end

原來這種用法叫做類別延伸 (class extenstion)。好處在於可以定義額外的 property, 實體
變數(需要定義在大括號裡)和方法來擴充類別,而在這個匿名的 category 所以定義的方法,
必須在這個類別的 implementation 區段實作。這些 private 的方法和 property 讓類別延伸也符合了 OO 中封裝 (Encapsulation) 的精神,不需要將實作的資料和內容被看見。
另外一個常見的 property 用法便是對外宣告為 readonly 對內為 readwrite:

// XYZPerson.h

@interface XYZPerson : NSObject
...
@property (readonly) NSString *uniqueIdentifier;
- (void)assignUniqueIdentifier;
@end

// XYZPerson.m 

@interface XYZPerson ()
@property (readwrite) NSString *uniqueIdentifier; // readwrite 是 default 的屬性所以也可省略不寫
@end

@implementation XYZPerson
...
@end

2014年11月12日 星期三

What is the use of "#pragma mark" in codes?

程式中的 #pragma mark 本身對程式碼並無意義,僅用來幫助組織編排程式,

方便將一群方法分類,以便於在 Jump bar 中快速查詢。

例如:

#pragma mark - 即是加一條分隔線。
#pragma mark Initialization 即是將以下的方法列於 Initialization 標題之下。

圖1. Jump bar

2014年10月30日 星期四

Object-C 語法摘要

類別、物件及方法

  1. Case Sensitive
  2. C:
    print("Hello %d", 1);
    Object-C:
    NSLog(@"Hello %i", 1); // NSLog 會自動換行
  3. C:
    a.print(2);
    Object-C:
    [ClassOrInstance method : params] -> [a print : 2];
  4. C:
    ClassA* A = new A();
    Object-C:
    ClassA* A = [[ClassA alloc] init];
    ClassA* A = [ClassA new];
  5. Object-C 支援 id 泛型, NSLog 用 "%p"。

迴圈、制定決策

  1. if, while, for, switch 的用法幾乎和 C 沒什麼不同。
    Note: 只有當 if (0) 的時侯為條件不成立,包括 nil 和 NO。
  2. BOOL 是用 YES/NO 表示,而不是 true/false。

類別、繼承

  1. Accessor Method 可以直接用下列語法表示:
    @interface ...
    @property int a;

    @implementation ...
    @synthesize a;   // XCode 4.5 之後 @synthesize 可省略
  2. 宣告於介面區段是屬於 public 的,而實作區段的的變數是屬於 private 的。
  3. 可用 #import "XYPoint.h" 也可用 @class XYPoint; 來引用類別,而使用
    @class 指令比較有效率,因為編譯器不需要處理整個 XYPoint.h。

類目與協定

  1. 多了 category 跟 protocol 的用法。( protocol 類似於 Java 的 interface)

Blocks


  1. 以 ^ 為開頭。
  2. 多當作 callback 來使用。
  3. 宣告在 blocks 之前的區域變數可以在 block 內引用(唯讀),除非在宣告變數時加上 __block。
  4. 在 block 裡引用 self 將會造成 Memory cycles,試著使用 weak reference:
    __weak MyClass *weakSelf self;


Ref: 精通 Object-C 程式設計 第六版