Wednesday, August 29, 2012

[DỊCH] Học ObjC trong 30 phút

Nói trước nhé: bài này mình dịch từ bài viết trên mạng: http://psionides.eu/2008/10/05/learn-objective-c-in-30-minutes/ có những chỗ hơi khó hiểu, các bạn đọc lại bản tiếng Anh, với có một chút chỗ em dịch không được, để tiếng Anh luôn, mấy bác tự xử....

//------------------------------------------------------------------------------------------------------


Học ObjC trong 30 phút

 

§        Thời gian gần đây tôi nghĩ về việc viết một vài thứ đơn giản về Objective C – bạn biết không, ngôn ngữ kì lạ Apple được sử dụng cho việc lập trình Mac…Tôi không định chuyển đổi từ Ruby sang ObjC – tôi khá thích thú với thử thách này (“cái gì, tôi không thể học điều này? Tất nhiên là bạn có thể!”), bên cạnh đó, không có ngôn ngữ nào là hoàn hảo, và có một vài ngôn ngữ cấp thấp mà bạn thật sự không nên viết trong Ruby, giống những plugin cho Finder, Quicklook,…Hơn nữa tôi cũng nhớ là đã đọc một vài chỗ mà nó thực sự tốt cho một lập trình viên để học một ngôn ngữ mới mỗi năm – do đó, cách đây 2 năm cho Python, một năm trước cho Ruby, và năm nay cho Objective C?:)
§        Tôi đã tìm trên google một vài bài hướng dẫn nhanh, đọc một số bài, và tôi thấy rằng ngôn ngữ này thực sự rất đơn giản, nó chỉ thấy phức tạp rắc rối do cú pháp và những ký hiệu; nhưng một khi bạn bắt đầu dịch mọi thứ trong đầu bạn, tất cả sẽ trở nên thật quen thuộc. Tất nhiên, đó là việc hoàn toàn khác để hiểu cái gì đang diễn ra với code của họ và để có thể viết code của chính bạn; nhưng trong trường hợp này, thật dễ dàng để đi từ “Oh my god, WTF cái quái gì đây?” đến trạng thái mà khi đó bạn có thể xem code ObjC và hiểu nó như thể là nó được viết trong Java hay một ngôn ngữ quen thuộc nào đó.
§        Tôi có một vài chú ý khi tôi đọc các bài hướng dẫn, và tôi đang viết ở đây để mọi người có thể học chúng nhanh hơn – đó chỉ là một “diff”, do đó tôi không mô tả chi tiết rõ ràng cho mọi người đã biết C, Java, Ruby,…Bạn có thể xem như là một bài hướng dẫn của một người đàn ông tội nghiệp…^^Mặc dù tôi cảnh báo bạn rằng tôi đã dành tổng cộng một ngày để xem code ObjC, cho nên một phần nào đó tôi đã viết ở đây có không hoàn toàn đúng. Tất cả những điều này được dựa trên những kiến thức tôi đã đọc, không phải là kinh nghiệm của tôi. Sản phẩm này được cung cấp mà không có bảo hành nhé…^^




The language

Ngôn ngữ

§        ObjC là một tập cha của C. Điều này có nghĩa là tất cả những thuộc tính được viết trong chương trình C về mặt lý thuyết được biên dịch như chương trình ObjC mà không có bất cứ sự thay đổi nào. Mọi thứ làm việc trong C, cũng làm việc trong ObjC. ObjC thêm một vài tính năng mới so với C, bao gồm OOP và Smalltalk-like message passing(truyền thông điệp Smalltalk-like).
§        ObjC là một ngôn ngữ mà nó được biên dịch thành mã máy, cũng giống như C/C++, và điều đó có lẽ làm cho nó nhanh hơn Java, Python hay Ruby, những ngôn ngữ chạy trong máy ảo.
§        Mặt khác, ObjC có nhiều tính năng mà làm nó linh hoạt hơn nhiều C++, và giống hơn với Ruby hay Python. ObjC hỗ trợ cả hai static typing và dynamic typing, dựa trên cách các biến được khai báo. Thật không may, tất cả những cái đó làm nó chậm hơn so với C++. Tôi không biết chậm hơn bao lâu, và tôi cũng không thể tìm ra một chuẩn riêng nào đó…Tôi đoán tôi cần phải tự mình viết.
§        Phiên bản mới nhất của ngôn ngữ này là 2.0 (cái này không biết bây giờ phiên bản mấy rồi :D),  nó được phát hành gần đây với Leopard; nó thêm một vài tính năng mới, giống như cơ chế thu dọn rác, những thuộc tính, hay vòng lặp for-each.

Source code

Mã nguồn

§        Những file được tổ chức theo cách giống như C/C++: có những file header (*.h), nó chứa những khai báo interface cho những lớp, và phần mã nguồn (*.m), mà nó cung cấp sự thực thi. Cảm ơn đến Stack Overflow, đuôi mở rộng .m có nghĩa là “messages” hay là “methods”.
§        Trong ObjC không có namespaces giống như những ngôn ngữ khác, thay vào đó, để có thể phân biệt những lớp từ những frameworks khác nhau, name prefixes được sử dụng. Ví dụ, nhiều lớp core ObjC có tiền tố “NS” (NSString, NSObject,…), viết tắt cho “NextStep” (nó là một môi trường Unix được tạo trong thập niên 90, mà nó được sử dụng như là một cơ sở cho MacOSX khi nó được phát triển.)
§        Thực thi chương trình bắt đầu trong hàm int main().
§        Những header có thể được include bằng cách sử dụng #include, nhưng sẽ tốt hơn khi dùng #import, cái này nó làm việc giống như include, ngoại trừ nó không bao giờ include cùng một header 2 lần (do đó bạn không phải làm những việc ngu ngốc như #ifndef/#define giống như bên C++).
§        Những từ khóa được thêm bắt đầu với “@” để phân biệt chúng với những từ khóa trong C.
§        Chương trình có được biên dịch bằng cách sử dụng gcc, giống như C/C++, những bạn cần thêm – framework Cocoa để sử dụng thư viện chuẩn ObjC (hoặc, nó được gọi trong ObjC, “framework”)

Methods

Phương thức
§        Đây là một điều thú vị nhất trong ObjC. Bạn không thể gọi những phương thức bằng cách: foo.bar, hay foo->bar, hay foo-whatever-bar. Bạn gọi chúng với [foo bar]…và obj.foo.bar thành [[obj foo] bar].  Một chút bất tiện IMHO, bởi vì khi bạn viết theo một trình tự “object method method method…” sau đó khi kết thúc bạn phải quay lại chỗ bắt đầu và thêm một số lượng những ngoặc đơn để nối với những dấu đóng ngoặc đơn… But once you install a proper regular expression in your head that changes bracket notation to dots, ít nhất là dễ đọc hơn.
§        Một điều bất thường về phương thức là những tham số trong đa số những trường hợp được cho bởi labels, chúng được dùng trong việc gọi phương thức. Do đó việc gọi những phương thức với nhiều hơn một tham số sẽ giống như thế này:
[appleStore buyMacs: 2 withRAM: 4 withCPU: 2.66]
§        Đây là một trong những ý tưởng được đưa ra từ Smalltalk. Nó làm code dài dòng hơn, nhưng ở khía cạnh khác, nó trở nên dễ đọc hơn nhiều. Bên cạnh đó, nó khá giống với những tham số của Python foo=bar  Ruby : foo=>bar, vì vậy thực sự không có gì mới.
§        Những label thực sự là từ tên đầy đủ của phương thức. Do đó phương thức ở trên đưa chuyển thành như: buyMacs:withRAM:withCPU:.
§        Những phương thức không thể được overload theo kiểu của tham số, do đó không thể có 2 phương thức foo(int)foo(char*). Nhưng chúng có thể được overload bằng labels, do đó bạn có thể có những phương thức như: buyMacs:, buyMacs:withRAM:, buyMacs:withMonitors: và …
§        Phương thức trên thường được dùng để thay thế cho default parameter values trong những hàm, mà chúng không tồn tại trong ObjC. Do đó nếu bạn muốn tham số thứ hai để có một giá trị mặc định, bạn phải viết 2 phương thức, một với một tham số, và cái khác với 2…
§        Giống như trong Python hay Ruby, việc gọi một phương thức không tồn tại thì không ném ra một lỗi biên dịch, nhưng nó ném ra một ngoại lệ runtime, cái đó có thể được bắt và xử lí.
§        Còn gì nửa?, việc gọi những phương thức không tồn tại có thể bị bắt lấy và được xử lý trước khi một ngoại lệ bị ném ra. Điều đó có nhắc bạn về việc gì không? method_missing của Ruby, tất nhiên. Ở đây, phương thức có thể được sử dụng cho điều này là: forwardInvocation:.
§        Những tác giả bài tut thông thường cứ khăn khăn là trong ObjC bạn không gọi những phương thức, bạn “gửi thông điệp”. Tôi nghĩ đây chỉ là một vấn đề về tên gọi, tôi không hiểu việc gọi phương thức với cái  “gửi thông điệp” khác nhau cái gì. Nhưng tôi cũng có thể sai.(Những phương thức cũng thể được gọi là những “selectors”).

Data types

§        ObjC có cả hay dạng primitiveobject, giống như C++ hay Java. Không giống như C++, nó không có kiểu giá trị cho những đối tưởng, mà chỉ có cho những con trỏ, do đó không có Foo x, mà chỉ là: Foo *x.
§        Kiểu dữ liệu thông thường của C (int, float, …) có thể được sử dụng, mặc dù đó có thể không thường xuyên được khuyến khích. Ví dụ, có những kiểu như NSInteger, NSUInteger, hay CGFloat, đó là những phiên bản kiến trúc an toàn cho int, unsigned int, float và …Cũng có một class được đặt tên là NSNumber được dùng cho boxing/unboxing những kiểu primitive trong những trường hợp khi chúng ta cần truyền một đối tượng đến nơi nào đó.
§        Ngoài kiểu chuỗi strings của C (char *), cũng có kiểu chuỗi của ObjC strings (NSString). Để tạo chuỗi kí tự, sử dụng kí hiệu: @”some text”. NSString có thể được chuyển thành char * bằng việc sử dụng cString () (cái này bị phản đổi..^^) hay những phương thức UTF8String của NSString (ví dụ, khi bạn cần sử dụng chúng như những tham số cho hàm printf()).
§        Boolean được gọi là BOOL, và giá trị của nó là…YESNO.
§        Có một kiểu chung được gọi là id, nghĩa gốc của nó là “any object”. Một cái gì đó giống Object *, nhưng có một sự khác nhau chút chút. Hay từ này là cánh cửa của kiểu đánh máy dynamic. Nếu bạn khai báo một biến là Foo *x, nó sẽ làm việc giống như C++, thử gọi một cái gì đó mà không hiệu lực trong lớp Foo, và trình biên dịch sẽ cảnh báo rằng (mặc dù trong ObjC nó không đóng với một lỗi, nó chỉ là in một cảnh báo -  bởi vì đôi khi mã có thể đúng, cho dù nó không rõ ràng đối với trình biên dịch ). Nhưng nếu bạn khai báo một biến như: id x, nó sẽ làm việc giống như trong Ruy – trình biên dịch cho phép bạn gọi bất cứ cái gì bạn muốn trên nó, và chỉ ở tại runtime nó sẽ được quyết định nếu đối tượng có thể xử lí method hay không.
§        Null được gọi là nil. Và apparently you can call methods on it and the universe won’t implode. Hơn thế nữa, bạn có thể gọi bất kì phương thức nào trên nó, và nó sẽ luôn return nil -  điều này có nghĩa là thông thường bạn không phải kiểm tra nếu đối tượng là nil. Bạn chỉ có thể gọi cái gì cũng được nếu bạn muốn trên nó, và nếu nó là nil, nó chỉ “ngồi” ở đó và bỏ qua bạn. Nó có thể làm cho việc code đơn giản hơn một xíu, nhưng mặt khác nó có thể làm cho việc debugging khó khăn hơn -  bạn không phải ngay lập tức lấy một ngoại lệ nếu cái gì đó không nên là nil…
§        Những con trỏ đến lớp (For pointers to classes), nil được viết hoa (Nil). Đừng hỏi tôi tại sao…
§        Giống như NSNumber cho ints, có một bộ cho giá trị nil – lớp NSNull. You can’t put a nil into an NSArray, but you can put a NSNull there (usage: [NSNull null]).
§        SEL (viết tắt cho “selector”) là một dạng của những con trỏ phương thức. Để lấy một con trỏ SEL. Sử dụng từ khóa @selector với chữ kí phương thức, vd: @selector(methodName:withArg:).
§        Tất cả những đối tượng có một phương thức được đặt tên là description, một cái tên giống như toString trong Java.
§        Nhiều dạng đối tượng built-in có những phiên bản mutablenon-mutable: có NSStringNSMutableString, NSArrayNSMutableArray, và nhiều cặp khác,…

Classes

§        Lớp interfaces (*.h) được khai báo được sử dụng với từ khóa @interface:
@interface MyClass: NSObject {  // <-- NSObject is the superclass
  // now, a list of instance variables:
  int foo;
  ...
}

// and now - a list of methods:
- (void) print;
- (void) setValue: (int) v;
- (void) setValue: (int) v andAnother: (int) a;
- (int) value;
- foo;
+ (int) numberOfInstances;
+ (void) initialize;  // class initializer

@end

§        Cú pháp định nghĩa phương thức khá khác với C/C++, nhưng nó khá dễ hiểu. Những phương thức với một kí hiệu – là những thể hiện của phương thức, và những cái đó với một dấu + là phương thức static.
§        ObjC sử dụng kế thừa đơn, giống như Java hay Ruby.
§        Nếu bạn không đề cập đến kiểu được return một cách rõ ràng (giống như phương thức foo ở trên), kiểu mặc định là id.
§        Nếu một lớp có một phương thức lớp đặt tên là initialize, nó được gọi một khi một lớp được sử dụng cho lần đầu tiên (giống như hàm tạo static trong C#).
§        Từ khóa khác được sử dụng trong khai báo interface, @class, được sử dụng cho khai báo trước, giống như C++. Nếu bạn cần đề cập một lớp trong interface của lớp khác, để giảm liên kết giữa những lớp mà bạn có thể khai báo nó với @class Klass thay vì #import <klass.h>.
§        Lớp implementation (*.m) được kèm theo từ khóa @implementation@end
@implementation MyClass

- (void) setValue: (int) v {
  ...
}

@end
§        Những khai báo biến không có kí hiệu +/- phía trước chúng, do đó nếu bạn muốn có một biến static trong một lớp, khai báo nó bằng cách sử dụng từ khóa C static trong file header, bên ngoài khối @interface (e.g. static int instances;).
§        Những biến được định nghĩa trong lớp được truy cập bằng cách sử dụng toán tử ->, ví dụ: person->name.
§        Biến truy cập được thiết lập bằng cách sử dụng từ khóa @public, @private, và @protected, chúng được sử dụng giống như trong C++ hay Ruby, không giống như trong Java – bạn thêm từ khóa trước một nhóm biến, không trước mỗi biến. Truy cập mặc định là @protected. Những phương thức thì luôn là public; bạn có thể mô phỏng những phương thức private không phải bằng cách thêm kí hiệu của chúng đến @interface, mà chỉ cần viết trong @implementation.
§        ObjC 2.0 giới thiệu “properties”, nó giống như thuộc tính đối tượng trong ngôn ngữ khác:
o        Bên trong @interface, trong khối phương thức mà bạn khai báo, ví dụ như: @property int age;. Việc này giống như bạn khai báo thủ công một getter (int) age (in ObjC getters không có tiền tố “get”) và một setter (void) setAge: (int) age. Bạn vẫn phải đề cập một việc nối biến được khai báo trong lớp trong khối biến.
o        Bên trong @ implementation, bạn viết là @synthesize age; nó tạo ra getter và setter cho biến. Bạn cũng có thể cung cấp những implementation tự chế của chính bạn.
o        Để tăng tính rắc rối ^^, những thuộc tính thì không được truy cập bằng [obj age] hay là obj->age, mà phải là obj.age
o        Những thuộc tính có thể có những tùy chọn cộng thêm được chèn trong ngoặc sau từ khóa @property, giống như ri: @property (readonly) int age;. Tùy chọn chỉ đọc có nghĩa là nó chỉ có getter được tạo ra.
§        Trong ObjC, một phần từ việc kế thừa từ những lớp, bạn cũng có thể…thêm code đến lớp đang tồn tại. Thậm chí trong những lớp built-in. Nghe có vẻ hơi dở, có chắc vậy không? Nó không mạnh như cơ chế “open classes” trong Ruby (ví dụ: bạn không thể thêm một biến instance mới), nhưng nó dường như lại là cách hay. Ở đây nó được gọi là “categoties” (bởi vì nếu bạn có một lớp dài, bạn có thể chứa những phương thức của nó trong một vài category và đặt chúng trong những file khác), và ở đây là cách nó thực hiện:
@interface ExistingClass (SomeNewName)
  ...methods...
@end
§        Sau khi bạn include cả hai header cũ và header mới trong file implementation, và voila – bạn có một lớp với những phương thức mới được thêm.
§        Cũng có cách thứ 2, một cơ chế gọi là “posing”. Với posing, thay vì thêm những phương thức đến một lớp được chọn, bạn tạo một lớp con của lớp đó, và sau đó bạn khai báo lớp con đó “pose” như lớp cha, có nghĩa là lớp cũ sẽ bị thay thế bằng một cái mới. Bạn làm điều này bằng cách sử dụng phương thức poseAsClass: [SubClass poseAsClass: [SuperClass class]];.
§        Hình như posing bị phản đối, do đó nó không thực dụ không nên được sử dụng bất cứ khi nào; Tôi chỉ vừa thêm nó ở đây để bạn biết cái này có nghĩa gì khi bạn thấy nó.

Loops, conditions and operators

§        Những cái này giống như bên C – for, while, if
§        Đối với tập hợp trong ObjC, bạn có thể sử dụng Java – giống như enumerators:
NSEnumerator *enum = [array objectEnumerator];
while (i = [enum nextObject]) {
  ...
}
§        Trong ObjC 2.0, cũng có vòng lặp for-each, được gọi là “fast enumeration” (bới vì nó hình như thuận tiện hơn cách cũ):
for (Foo *foo in list) {
  ...
}
§        Toán tử so sánh object identity ==, và so sánh giá trị bạn cần gọi một hàm: [x isEqual: y].

Objects

Đối tượng
§        Bên trong những phương thức object,việc tham chiếu đến đối tượng được gọi là self, giống như trong Python hay Ruby.
§        Để gọi những hàm implementations của superclass, ta sử dụng tham chiếu super. Ví dụ, [super foo] gọi là phiên bản của super của phương thức foo.
§        Việc tạo những đối tượng gồm 2 phần: đầu tiên là ta gọi alloc trên class để  phân bổ bộ nhớ, sao đó init (hay một việc khác nào đó, hoặc khởi tạo giá trị cụ thể nào đó) trên đối tượng để khởi tạo nó, vì thế nó giống như thế này: 
Mac *box = [[Mac alloc] init];
§        Nếu tôi nhớ không nhầm thì, nó giống như trong Ruby, nhưng nó có những vấn đề phía sau ngữ cảnh - Foo#allocateFoo#initialize được gọi khi bạn viết Foo.new.
§        Nếu bạn muốn có một vài hàm tạo biến thể, bạn có thể viết chúng giống như thế này:
- (ClassName*) initWithParam: (int) one andAnother: (int) two {
  // first, call any initializations defined in superclass
  self = [super init];

  if (self) {  // self could be nil if something went wrong
    // ... set some instance variables and stuff
  }

  return self;  // won't work without this
}

Và sau đó bạn sử dụng nó giống như thế này:
ClassName* var = [[ClassName alloc] initWithParam: 5 andAnother: 6];

Protocols

Giao thức
§        Những protocol về cơ bản nó giống như interface của java - danh sách của những phương thức mà không implement, mà chúng có thể được implement bởi những lớp. Việc khai báo những protocol giống như khai báo một lớp:
@protocol FooInterface
- (int) foo;
- (void) bar;
@end
§        Để đánh dấu một lớp như là việc implement một interface, thì ta thêm tên interface trong  cặp dấu: <>
@interface MyClass: NSObject <Printable, FooInterface>
§        Những phương thức được khai báo trong implemented protocol thì không cần được liệt kê bên trong khai báo @interface.
§        Giống như trong Java, bạn có thể khai báo những biến mà nó trỏ đến bất kì cái gì mà implement một interface:
id foo = [[MyClass alloc] init];
§        Bạn có thể gán bất kì đối tượng nào đến biến foo, miễn là nó implement FooInterface.
§        Cũng có thể được gọi là: "informal protocols", chúng chỉ là những danh sách của các phương thức được publish ở một nơi nào đó trong tài liệu mà lớp của bạn phải hoặc có thể định nghĩa, nhưng thực tế của việc implement protocol thì không được đề cập rõ ràng trong code. Điều này thường được làm bằng cách thêm một category đến một lớp, được đặt tên giống như protocol, cái này nó chứa những phương thức được yêu cầu.

Memory management

Quản lý bộ nhớ
§        Phiên bản cũ: giống như C, ObjC dựa trên nó, bạn phải nhớ release tất cả bộ nhớ mà bạn cấp phát, và nếu bạn quên điều đó, bạn sẽ thấy leak (rò rỉ) bộ nhớ (và nếu bạn release quá nhiều, bạn sẽ bị  segfaults).
§        Phiên bản mới (từ 2.0 trở lên): ObjC bao gồm garbage collector (bộ thu nhặt rác), do đó bạn chỉ việc bật nó trong settings của Xcode và quên cái việc quản lý bộ nhớ :) . Nó khá bất thường cho một ngôn ngữ được biên dịch đầy đủ để có một garbage collector, và nó làm cho ObjC khá là độc đáo (đặc trưng).
§        Nhưng việc giới thiệu garbage collector trong phiên bản 2.0 không có nghĩa là mọi người sẽ bắt đầu sử dụng ngay lập tức (nó chưa được kích hoạt trên iphone), do đó ở đây có một vài chi tiết về quản lý bộ nhớ:

o                       Ngay cả khi không có garbage collector, việc quản lý bộ nhớ thì nó đơn giản hơn chút so với C/C++.
o                       Sự khác nhau ở đây là bạn không phải suy nghĩ chính xác là ai nên có trách nhiệm cho việc phá huỷ một đối tượng. Mỗi lần bạn chứa một tham chiếu đến nó, bạn gọi [obj retain], mà nó tăng "retain count" của nó lên (số lượng những tham chiếu); và khi bạn không cần nó nửa, bạn gọi [obj release].  Nếu bạn làm retain count về 0 (nó bắt đầu lúc 1), đối tượng sẽ được release, nếu không -  không có gì xảy ra. Do đó mỗi đối tượng có thể có vài "owners" và they all dispose of it in the same way.
o                       Khi đối tượng bị huỷ, hàm huỷ của nó -  một phương thức được gọi là dealloc -  sẽ được gọi. Trong phương thức này, bạn có thể gọi release trên tất cả những tham chiếu đến những đối tượng khác mà bạn chứa trong đối tượng đó. Bạn nên gọi dealloc của super.
o                       Khi garbage collector được bật lên, tất cả những phương thức giống retain, release,... được bỏ qua, và dealloc được gọi. Thay vào đó,  phương thức finalize gets được gọi khi một đối tượng được garbage collected.
o                       Cách khác để quản lý bộ nhớ là điều gì đó được gọi là "autorelease pools". Chúng là dạng đa quản lý đối tượng, những trường hợp của lớp NSAutoreleasePool, và bạn có thể gán những đối tượng đến chúng bằng cách dùng [obj autorelease]. Sau đó, khi một autorelease pool được release (sử dụng [pool drain]) - thuật ngữ tuyệt vời :), nó tự động release tất cả những đối tượng gán đến nó.
o                       Bạn phải cẩn thận về những đối tượng mà nó đã autorelease khi bạn get chúng, và chúng nên được (auto ) release bởi bạn. Ví dụ, những đối tượng được tạo ra mà không alloc, nhưng đang dùng phương thức thức static trong những lớp cơ bản giống như NSString, ví dụ [NSString stringWithFormat: ...] (một cái gì đó nó giống sprintf()), thường là nó đã được autorelease. Bạn không thể gọi release chúng, bởi vì điều đó sẽ gây ra một segfault khi pool cố gắng release chúng. Luật chung là: khi bạn tạo một đối tượng sử dụng phương thức alloc hay copy, bạn cần release chúng, and if you get it through some other means, usually someone else will release it.
o                       Với release/retain, bạn cũng phải cẩn thận cách bạn viết thuộc tính setters (nếu bạn không dùng @synthesize). Bạn phải release cả hai đối tượng cũ và retain đối tượng mới; nhưng bạn không thể release trước khi bạn retain, bởi vì nếu bạn trỏ đền cùng một đối tượng, nó sẽ bị deallocated khi release. Do đó bạn phải gọi retain trước khi release, hay kiểm tra con trỏ nếu chúng không cùng thời điểm bắt đầu của setter, hay sử dụng autorelease thay vì release.

Reflection

§        ObjC thì nó năng động hơn C hay C++, mặc dù thực tế là nó là ngôn ngữ được biên dịch mạnh mẽ. Ở đây là một vài ví dụ của những hàm liên quan đến reflection:
o                       isKindOfClassisMemberOfClass – like kind_of?, instance_of? in Ruby
o                       respondsToSelectorinstancesRespondToSelector – tells if an object has a specific method (like respond_to? in Ruby)
o                       Có nghĩa là nếu một đồi tượng có một phương thức cụ thể (giống như respond_to? trong Ruby)
o                       performSelector – calls a specified method on the object (like send(:method_name)) (gọi một phương thức xác định trên một đối tượng) (giống như send(:method_name))
o                       conformsToProtocol(@protocol(FooInterface)) – tells if a class implements a protocol - có nghĩa là nếu một lớp implements một protocol.

Exceptions and debugging

§        Những ngoại lệ làm việc giống như những ngôn ngữ hiện đại khác: chúng được đại diện bởi những lớp kế thừa từ NSException, và bạn sử dụng từ khoá @try, @catch@finally để chặn ngoại lệ được ném ra trong một khối và xử lí chúng. Sử dụng @throw e để ném ngoại lệ e, và @throw để ném lại một ngoại lệ trong khối catch.
§        Hai phương thức mà có lẽ hữu ích trong debugging:
o                       NSAssert(x != 0, @"X must not be zero") – throws exception if x == 0
o                       ném ngoại lệ nếu x==0;
o                       NSLog(@"foo bar %@", x) – outputs the string (+ some info) on stderr, and also adds the same line to /var/log/system.log (which can be viewed with “Console” application).
o                       Đầu ra là chuỗi (+ một vài thông tin) trên stderr, và cũng thêm cùng dòng đến  /var/log/system.log (mà có thể được xem với ứng dụng Console).

Và đó là tất cả…nếu bạn không biết xíu nào về ObjC, và bạn đã có tính nhẫn nại để đọc hết bài viết này, tôi hi vọng bạn sẽ có một vài kiến thức về ObjC. Dù sao đi nữa, bây giờ bạn không nên vừa chạy vừa hét khi bạn thấy code ObjC…ít nhất là tôi sẽ không làm như vậy…;)