Sự khác biệt giữa Category và Class Extension?


85

Sự khác biệt giữa Category và Class Extension là gì. Tôi tin rằng cả hai đều được sử dụng để thêm các phương thức tùy chỉnh trong các lớp hiện có. Ai đó có thể ném ánh sáng vào điều này? Examplification với mã sẽ thực sự được đánh giá cao.



3
Akusete, không thể tìm thấy trang.
Adil Hussain

được minh họa rõ ràng ở đây, code.tutsplus.com/tutorials/…
grassyburrito

Câu trả lời:


103

Category là một cách để thêm các phương thức vào các lớp hiện có. Chúng thường nằm trong các tệp có tên "Class + CategoryName.h", như "NSView + CustomAdditions.h" (và .m, tất nhiên).

Phần mở rộng lớp học là một danh mục, ngoại trừ 2 điểm khác biệt chính:

  1. Danh mục không có tên. Nó được khai báo như thế này:

    @interface SomeClass ()
    
    
    - (void) anAdditionalMethod;
    
    @kết thúc
  2. Việc triển khai phần mở rộng phải nằm trong khối @implementation chính của tệp.

Khá phổ biến khi thấy một phần mở rộng lớp ở đầu tệp .m khai báo nhiều phương thức hơn trên lớp, sau đó được triển khai bên dưới trong phần @implementation chính của lớp. Đây là một cách để khai báo các phương thức "pseudo-private" (pseudo-private ở chỗ chúng không thực sự riêng tư, chỉ là không lộ ra bên ngoài).


13
Trong Class-Extensiosn, bạn có thể ghi đè các thuộc tính từ thuộc tính chỉ đọc (công khai) để được ghi nội bộ. Và vì LLVM 1.5, bạn còn có thể làm được nhiều hơn thế nữa: giờ đây bạn có thể khai báo các biến cá thể trong phần mở rộng lớp để chúng biến mất khỏi giao diện thông thường.
Max Seelemann

Tại sao lại thêm phần mở rộng lớp khi bạn chỉ có thể triển khai các phương thức và thuộc tính đó vào lớp? Có vẻ hơi thừa đối với tôi.
user1721803

1
@ user1721803 Như Dave đã đề xuất, bạn có thể muốn giữ một số thuộc tính / phương thức không bị phơi sáng. Đây là khi phần mở rộng được sử dụng. Hãy xem xét một chế độ xem, bạn có thể kết nối tất cả IBOutlets và IBActions của mình trong phần mở rộng và hiển thị các phương thức cho phép khởi tạo / cập nhật Outlets và Actions có thể được ủy quyền trở lại.
GoodSp33d

@MaxSeelemann, bạn có thể vui lòng giới thiệu cách biến "thuộc tính chỉ đọc (công khai) thành thuộc tính chỉ đọc nội bộ" bằng một đoạn mã ngắn không? Cảm ơn.
allenlinli

Câu trả lời này cho biết phần mở rộng trong tệp "Class + CategoryName.swift", có đúng không ??
Rishi

47
  1. thể loại

=> Trong Objective C, khi bạn muốn thêm một số chức năng vào một lớp không có tính kế thừa, bạn chỉ cần sử dụng category cho nó.

=> nó đi kèm với tệp .h.m của riêng nó

=> Categorydùng để thêm thuộc tính của method mới.

  1. Mở rộng lớp học
-> In Objective C, when you want to make behaviour of some property private you use class extension.

-> it comes with **.h** file only.

-> mainly for properties.

Lưu ý: khi chúng tôi thêm một tệp mới và chọn một tùy chọn của danh mục c mục tiêu sẽ hiển thị danh mục và "danh mục trên" không phải "lớp con của" nên nó hiển thị như

@interface className (categoryName)
@end

-Bạn sẽ nhận được hai tệp .h.m với tên tệp là ( className + categoryName.hclassName + categoryName.m )

và trong trường hợp mở rộng, bạn sẽ nhận được

@interface className()
@end

-Bạn sẽ chỉ nhận được một tệp có tên là className_extensionName.h

  • Trong danh mục bạn không sở hữu lớp học nhưng trong phần mở rộng bạn có.

5
@Prasanna: phần mở rộng lớp chỉ đi kèm với tệp .m và không có trong .h
Saggy

1
mở rộng lớp đi kèm với một tập tin .h chỉ và không phải là một .m
Nishu_Priya

32
  1. Category là một cách để thêm các phương thức vào một lớp cho dù có mã nguồn hay không, có nghĩa là bạn có thể thêm thể loại vào các lớp nền tảng như NSStringvà cả các lớp tùy chỉnh của riêng bạn.

    Phần mở rộng chỉ có thể được thêm vào các lớp có mã nguồn vì trình biên dịch biên dịch mã nguồn và phần mở rộng cùng một lúc.

  2. Chúng ta có thể thêm các biến cá thể và thuộc tính bổ sung trong phần mở rộng lớp nhưng không phải trong danh mục.

  3. Bất kỳ biến và phương thức nào bên trong tiện ích mở rộng thậm chí không thể truy cập được đối với các lớp kế thừa.

  4. Danh mục và phần mở rộng về cơ bản đều được tạo ra để xử lý cơ sở mã lớn, nhưng danh mục là một cách để mở rộng API lớp trong nhiều tệp nguồn trong khi tiện ích mở rộng là một cách để thêm các phương thức bắt buộc bên ngoài tệp giao diện chính.

  5. Sử dụng danh mục khi bạn phải chia cùng một mã lớp của mình thành các tệp nguồn khác nhau theo các chức năng khác nhau và phần mở rộng khi bạn chỉ cần thêm một số phương thức bắt buộc vào lớp hiện có bên ngoài tệp giao diện chính. Ngoài ra, khi bạn cần sửa đổi một biến phiên bản được khai báo công khai trong một lớp, chẳng hạn như chỉ đọc để đọc ghi, bạn có thể khai báo lại nó trong phần mở rộng.


3
Tôi đọc 5 câu hỏi tương tự với nhiều câu trả lời, và đây là câu trả lời hay nhất. Cảm ơn bạn!
Honey

1
Bạn cũng có thể thêm các thuộc tính trong danh mục. Xem câu trả lời của @Pebby.
atulkhatri

7

Phần mở rộng : Để đặt các phương thức ở chế độ riêng tư và thêm các thuộc tính của lớp tùy chỉnh của riêng chúng tôi, không phải của lớp Apple.

Category : Để thêm nhiều phương thức hơn trong lớp hiện có không phải thuộc tính, nó có thể được sử dụng cho cả lớp tùy chỉnh và lớp Apple như NSString.


Đơn giản và thanh lịch. Giữ nó lên
Abdul Yasin

3

Chúng ta cũng có thể có các thuộc tính Sử dụng thuộc tính liên kết tập hợp trong lớp danh mục.

@interface SomeClass (Private)

@property (nonatomic, assign) id newProperty;

@end

NSString * const kNewPropertyKey = @"kNewPropertyKey";

@implementation SomeClass (Private)

@dynamic newProperty;

- (void)setNewProperty:(id)aObject
{
    objc_setAssociatedObject(self, kNewPropertyKey, aObject, OBJC_ASSOCIATION_ASSIGN);
}

- (id)newProperty
{
    return objc_getAssociatedObject(self, kNewPropertyKey);
}

@end

Tham khảo: http://inchoo.net/dev-talk/ios-development/how-to-add-a-property-via-class-category/


2
@interface SomeClass ()


- (void) anAdditionalMethod;


@end

Tôi nghĩ đó không phải là cách để khai báo Category. Danh mục phải có tên

@interface SomeClass (XYZ)


- (void) anAdditionalMethod;


@end

ví dụ

@interface NSMutableArray (NSMutableArrayCreation)

+ (id)arrayWithCapacity:(NSUInteger)numItems;
- (id)initWithCapacity:(NSUInteger)numItems;

@end

Được Apple tuyên bố cho NSMutableArray


Đây là cách bạn khai báo và phần mở rộng, không phải là một loại -> @ interface SomeClass ()
ChavirA

0

phần mở rộng ios tương tự với c #, java lớp trừu tượng hoặc giao diện
danh mục ios tương tự như c #, phần mở rộng lớp java


4
câu trả lời của bạn giống như "mèo tương tư hổ, trả lời một người mù". Lol
Muruganandham K

1
nó không thực sự. Đây là lời giải thích trực tiếp và nhanh chóng nhất nếu bạn biết c # hoặc java.
Add080bbA

Không có gì mô tả cả, và hầu như không trả lời được câu hỏi.
KVISH

0

Thể loại

Các danh mục được sử dụng khi bạn đang tạo tệp có chứa một số lượng lớn các phương thức, vì vậy chúng cung cấp cho bạn cơ sở để chia một lớp thành các mô-đun khác nhau.Ngoài ra, nếu có bất kỳ thay đổi nào đối với các danh mục, trình biên dịch sẽ không lãng phí thời gian để biên dịch toàn bộ dự án . Các danh mục không thể thêm biến hoặc thuộc tính mới và tìm đến lớp cha của chúng. Bạn có thể ghi đè một phương thức trong một danh mục nhưng đó không phải là ý kiến ​​hay vì không thể ghi đè phương thức này nữa. Ngoài ra, quy trình có thể được thực hiện vì tất cả các danh mục đều có cùng mức phân cấp và do đó hai danh mục thuộc cùng một lớp cha có thể tồn tại trong thời gian chạy. Ngoài ra, các phương thức được bảo vệ có thể được tạo bằng cách sử dụng các danh mục

Phần mở rộng

Các tiện ích mở rộng cho phép bạn ghi đè thuộc tính hoặc thêm thuộc tính mới vào lớp cha hiện có. Tổng hợp giống nhau đối với các danh mục mà chúng không có tên và được đại diện dưới dạng lớp @interface () Không có tệp .m và phương thức được khai báo trong phần mở rộng phải được triển khai trong @implementation của tệp mẹ

Thêm trợ giúp tại liên kết này


0

Đây là sự hiểu biết của tôi:

Các tiện ích mở rộng thường được sử dụng để thêm các tính năng bổ sung vào " lớp tùy chỉnh " của riêng chúng tôi . Chúng ta có thể thêm các phương thức hoặc thuộc tính private mở rộng giao diện lớp có thể được sử dụng trong quá trình triển khai của lớp.

Các phần mở rộng phải được viết trong cùng một tệp với lớp. Do đó, bạn không thể viết phần mở rộng cho các loại được xác định trước như String, Float, v.v.

Mặt khác, các Category có thể được sử dụng để thêm các phương thức bổ sung vào các lớp đã có từ trước. Ví dụ, chúng ta có thể tạo các phương thức của riêng mình bằng cách mở rộng lớp String. Lưu ý rằng chúng tôi không thể tạo thêm thuộc tính trong các danh mục. Ngoài ra, lợi thế chính của danh mục là chúng ta có thể ghi các danh mục trong bất kỳ tệp nào khác, bên ngoài tệp mà lớp của bạn thoát ra.

Ngoài ra, trong khi tạo các danh mục, bạn phải đặt tên cho nó trong dấu ngoặc. Nhưng đối với phần mở rộng thì không cần tên. Do đó, đôi khi chúng còn được gọi là danh mục ẩn danh.


Bạn đang đi chệch hướng.
Abdul Yasin

@iPhoneDeveloper Chúng tôi có thể viết phần mở rộng cho các loại được xác định trước. Vui lòng kiểm tra liên kết này - stackoverflow.com/a/33942484/2060508
yo2bh
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.