Chính xác thì cái gọi là “Cụm lớp” trong Objective-C là gì?


91

Tôi đã đọc rằng NSArray chỉ là một thứ như vậy. Nghe có vẻ nặng nề. Tôi có 7 cuốn sách thực sự hấp dẫn ở đây trên bàn về Objective-C, Cocoa và C. Không có cuốn nào đề cập đến Class Cluster cả, ít nhất tôi không thể tìm thấy nó trong Mục lục ở cuối sách. Vậy đó là gì?


Rất tiếc, lần sau tôi sẽ nghĩ đến việc thêm liên kết cho thuật ngữ đó. Nếu bạn nhận xét về câu trả lời cho bạn câu hỏi trước, tôi đã trả lời ở đó.
Georg Fritzsche

2
FWIW: gần đây (tháng 12 năm 2013) Apple đã khuyến nghị sử dụng Class Clusters như một cách để xử lý tính tương thích ngược với iOS 6 khi sử dụng iOS 7. Điều này đã có trên Apple Tech Talks 2013 / Berlin trong phiên "Kiến trúc ứng dụng hiện đại, Phần 2". Apple cho biết họ sẽ đăng video về các phiên họp ngay sau sự kiện cuối cùng (17/12). Vì vậy, có thể điều này sẽ giúp hiểu các Cụm lớp trong bối cảnh thực tế của những thay đổi trên iOS 6/7.
brainray 17/1213

Câu trả lời:


42

Từ tài liệu của Apple ... . Tóm lại, đó là một mẫu thiết kế được sử dụng trong khuôn khổ Foundation, đó có thể là lý do tại sao nó không được đề cập trong các sách của ObjC.

Cụm lớp là một kiến ​​trúc nhóm một số lớp con cụ thể, riêng tư dưới một lớp cha trừu tượng, công khai. Việc nhóm các lớp theo cách này cung cấp một giao diện đơn giản hóa cho người dùng, người chỉ nhìn thấy kiến ​​trúc hiển thị công khai.


1
roflmao. cảm ơn. sẽ google lần sau. Hãy nghĩ nếu nó không có trong những cuốn sách béo bở của tôi, nó chỉ có thể nằm trên đầu bạn;)
openfrog

1
Một điều mà liên kết này còn thiếu là giải thích về cách thay đổi tốt nhất việc triển khai cho ARC.
Hyperbole

193

Tôi không biết có gì trong CDP mà Steve đã tham chiếu nhưng về cơ bản thì Objective-C Class Cluster là một cấu trúc hỗ trợ triển khai mô hình Factory trừu tượng .

Các ý tưởng rất đơn giản : Bạn muốn cung cấp một máy (Cluster) giao diện đó, với mô tả tối thiểu, sản xuất và lợi nhuận một trường hợp cụ thể cụ thể của một đối tượng Factory rằng đáp ứng hành vi của các gia đình cụm mô tả bởi giao diện Factory (Cluster).

Một ví dụ cụ thể đơn giản : Ví dụ này cung cấp một nhà máy Laugh sản xuất các lớp bê tông của các loại tiếng cười cụ thể (ví dụ: Guffaw, Giggle). Hãy chú ý đến phương thức Laugh initWithLaughter:.

Trong Laugh.h:

#define kLaughWithGuffaw  1
#define kLaughWithGiggle  2

@interface Laugh: NSObject {}
- (Laugh *) initWithLaughter:(NSUInteger) laughterType;
- (void) laugh;
@end

Trong Laugh.m:

@interface Guffaws:Laugh {}
- (void) laugh;
@end

@interface Giggles:Laugh {}
- (void) laugh;
@end

@implementation Laugh
- (Laugh *) initWithLaughter:(NSUInteger) laugherType {
    id instanceReturn=nil;
    ; // Removed for ARC [self release]
    if ( laughterType == kLaughWithGuffaw )
        instanceReturn = [[Guffaws alloc]init];
    else if( laughterType == kLaughWithGiggle )
        instanceReturn = [[Giggles alloc]init];
    else
        ; // deal with this
    return instanceReturn;
}

- (void) laugh {
    NSLog(@"Humbug");
}
@end

@implementation Guffaws
    - (void) laugh {
        NSLog(@"OH HA HA HOWAH HA HA HA");
    }
@end

@implementation Giggles
    - (void) laugh {
        NSLog(@"Tee hee");
    }
@end

24
Mặc dù các câu trả lời khác rất tốt khi cung cấp liên kết tài liệu và sách, nhưng tôi thích điều này vì nó giúp bạn thấy cách thực hiện việc này thật hay và đơn giản. Cảm ơn
jamone

Ví dụ này là tốt nhưng trong một mẫu Factory điển hình, các lớp con là công khai. Trong một cụm Lớp, các lớp con là riêng tư. developer.apple.com/library/ios/documentation/general/…
maxpower

1
@ AdriàNavarro Chúng không được nhìn thấy bên ngoài vì chúng được khai báo trong .m-file.
hfossli

4
(1) Mức độ an toàn khi giải phóng bản thân trong một initphương pháp và trả lại một thứ khác? Có bất kỳ ví dụ mã nào từ Apple nơi họ làm điều này không? (2) Ngoài ra, có lẽ bạn đang tạo một phiên bản với mã chẳng hạn như [[Laugh alloc] initWithLaughter:kLaughWithGiggle]. Lưu ý cách Laughđược cấp phát không cần thiết, vì nó sẽ được phát hành ngay sau cuộc gọi này. Tại sao lại làm theo cách này khi bạn có thể tạo một phương thức lớp, chẳng hạn như phương thức [Laugh laughWithLaughter:kLaughWithGiggle]này mang lại cho bạn tất cả các lợi thế của các lớp con riêng tư, đồng thời tránh được các vấn đề 1 & 2 ở trên?
Senseful

1
@Senseful Bạn nói đúng. Trong cuộc sống thực, +alloctrả về một lớp nhà máy singleton thực hiện các -initWith:phương thức khác nhau . Lớp nhà máy của-initWith: phương thức sau đó chịu trách nhiệm cấp phát và khởi tạo một lớp con cụ thể dựa trên các tham số phương thức đã cho, nếu cần, hoặc trong một số trường hợp có thể không cấp phát bất cứ thứ gì (chẳng hạn như -[NSString initWithString:]). Bạn có thể thử nó bằng cách kiểm tra tại các giá trị trả về của +[NSString alloc], +[NSArray alloc]vv
Darren

25

Từ lập trình trong mục tiêu c của Stephen Kochan trên trang 498 trong bảng chú giải thuật ngữ, cụm:

Một lớp trừu tượng nhóm một tập hợp các lớp con cụ thể riêng, cung cấp giao diện đơn giản hóa cho người dùng thông qua lớp trừu tượng.


5
+1 Để trích dẫn câu trả lời từ sách Objective-C, đặc biệt là với câu hỏi gốc. Đó cũng là một cuốn sách hay.
Quinn Taylor

(+1) cho định nghĩa tuyệt vời. Vấn đề tôi gặp phải khi gọi đây là mẫu "Nhà máy" là tên như vậy chỉ tập trung vào việc tạo ra các đối tượng, chứ không phải các tương tác ẩn của các lớp con riêng tư như được quản lý bởi lớp cha trừu tượng. Thật vậy, ngay cả việc gọi siêu lớp này là "trừu tượng" cũng có thể gây hiểu lầm vì nó thực tế khá phụ thuộc (nội bộ) vào các lớp con của chính nó, và do đó không phải là một lớp trừu tượng bình thường mà thường không biết gì về các lớp con của nó.
devos1

18

Các cụm lớp cung cấp một giao diện công khai duy nhất cho một nhóm triển khai lớp con cụ thể, riêng tư. Một lập trình viên target-c thường xuyên sử dụng các cụm lớp và hiếm khi nhận ra nó - và đây là toàn bộ điểm của một cụm lớp. Công việc của một cụm lớp là che giấu sự phức tạp của chi tiết triển khai đằng sau một giao diện công khai.

Nhiều lớp Foundation là các cụm lớp, chẳng hạn như NSString, NSArray, NSDictionary và NSNumber. Khi bạn gọi [NSString stringWithFormat:]cụm lớp sẽ cung cấp cho bạn một số lớp cụ thể triển khai NSStringgiao diện. Đó có thể là NSConcreteString, NSCFString,NSFooBarString , vv Mà cụm lớp mang đến cho bạn dựa trên các nhà xây dựng hoặc khởi tạo bạn đang gọi và các đối số.

Do đó, cụm lớp là một trong những khái niệm mạnh mẽ nhất trong lập trình Objective-C.

  • Rất dễ thực hiện
  • Dễ dàng thay đổi triển khai cơ bản mà không cần thay đổi mã gọi nó.
  • Dễ dàng cung cấp các triển khai cụ thể khác nhau trong thời gian chạy (tức là tài nguyên thử nghiệm hoặc đối tượng giả)
  • Vì những điều trên, dễ dàng kiểm tra và cấu trúc lại

Nếu bạn đến từ các ngôn ngữ khác, bạn có thể quen thuộc với các mẫu Gang of Four. Các cụm lớp có các yếu tố của cả nhà máy trừu tượng và các mẫu mặt tiền.

Tài liệu công khai của Apple bao gồm các cụm lớp (và cách triển khai và mở rộng chúng) khá rộng rãi. Thật không may, tôi nhận thấy rằng đối với nhiều nhà phát triển iOS, điều này và các mô hình dành riêng cho Cocoa khác là một điểm mù.

Năng lực cốt lõi của ca cao: Cụm lớp

Hướng dẫn cơ bản về ca cao: Cụm lớp

Ví dụ về cách triển khai các cụm lớp của riêng bạn có sẵn trên GitHub


7

Cụm lớp NSArray không phải là "nặng ký", nó là một cách để sử dụng bất kỳ số lượng triển khai nào của một lớp mảng mà mã của bạn không biết hoặc quan tâm đến việc triển khai cụ thể. Dưới mui xe, có các lớp con cụ thể của NSArray phù hợp với các trường hợp sử dụng khác nhau, chẳng hạn như mảng lớn, thưa thớt hoặc mảng chứa một số phần tử cụ thể đã biết tại thời điểm biên dịch.

NSArray, NSString và NSNumber là các cụm lớp mà bạn thường gặp nhất.


6
Trớ trêu thay, trong thực tế, chỉ có một lớp cụ thể cho mỗi cụm được sử dụng nữa - NSCF {Array | String | Number} - và các thay đổi triển khai là nội bộ của lớp đó. Đó là theo như tôi biết, dù sao. Ngay cả các thể hiện NSArray và NSMutableArray cũng hiển thị cùng một lớp.
Chuck

1
@Chuck - làm thế nào đây có thể là trường hợp? Nếu một NSMutableArray và NSArray tự báo cáo là cùng một lớp sẽ không [myArray isKindOfClass:[NSMutableArray class]]trả về CÓ mặc dù không nên?
Robert

1
@Robert: Và thực sự đó là trường hợp vào thời điểm nhận xét của tôi. Ngày nay Apple đã thay thế NSCFArray bằng __NSArrayM và __NSArrayI, vì vậy tôi nghĩ rằng nó không còn như vậy nữa, nhưng tôi vẫn không cảm thấy thoải mái khi phụ thuộc vào nó, vì họ luôn có thể thay đổi lại nó.
Chuck
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.