カテゴリとクラス拡張子の違いは?


85

カテゴリとクラス拡張の違いは何ですか。どちらも既存のクラスにカスタムメソッドを追加するために使用されていると思います。誰かがこれに光を当てることができますか?コードによる例証は本当にありがたいです。



3
Akusete、ページが見つかりません。
アディルフセイン2014

ここに明確に示されている、code.tutsplus.com
tutorials

回答:


103

カテゴリは、既存のクラスにメソッドを追加する方法です。これらは通常、「NSView + CustomAdditions.h」(もちろん.m)などの「Class + CategoryName.h」というファイルにあります。

クラス拡張は、2つの主な違いを除いて、カテゴリです。

  1. カテゴリに名前はありません。次のように宣言されます。

    @interface SomeClass()
    
    
    - (void) anAdditionalMethod;
    
    @終わり
  2. 拡張機能の実装は、ファイルのメインの@implementationブロックにある必要があります。

.mファイルの先頭にクラス拡張子があり、クラスのメソッドをさらに宣言しているのはよくあることです。これらのメソッドは、以下のクラスのメインの@implementationセクションに実装されています。これは、「pseudo-private」メソッドを宣言する方法です(pseudo-privateは、実際にはプライベートではなく、外部に公開されていないだけです)。


13
Class-Extensiosnでは、(パブリック)読み取り専用プロパティのプロパティを上書きして、内部で読み取り/書き込みを行うことができます。また、LLVM 1.5以降、さらに多くのことができるようになりました。クラス拡張でインスタンス変数を宣言して、通常のインターフェイスから削除できるようになりました。
Max Seelemann 2010

これらのメソッドとプロパティをクラスに実装できるのに、なぜクラス拡張を追加するのですか?私には少し冗長に思えます。
user1721803 2014

1
@ user1721803 Daveが提案したように、いくつかのプロパティ/メソッドを公開しないでおくことをお勧めします。これは、拡張機能が使用される場合です。ビューについて考えてみましょう。すべてのIBOutletsとIBActionsを拡張機能に接続し、OutletsとActionsを初期化/更新できるメソッドを公開して委任することができます。
goodSp33d 2014

@MaxSeelemann短いスクリプトで「(パブリック)読み取り専用プロパティを内部で読み取り/書き込み可能にする」方法をデモしていただけますか?ありがとう。
allenlinli 2017年

この回答は、「Class + CategoryName.swift」ファイルの拡張子を示していますが、正しいですか?
リシ

47
  1. カテゴリー

=> Objective Cでは、継承なしでクラスに機能を追加したい場合は、単にカテゴリを使用します。

=>独自の.hおよび.mファイルが付属しています

=>Categoryプロパティではなく新しいメソッドを追加するために使用します。

  1. クラス拡張
-> 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.

注:新しいファイルを追加してObjective Cのオプションを選択すると、カテゴリは「のサブクラス」ではなく「カテゴリ」と「カテゴリオン」を表示するため、次のように表示されます。

@interface className (categoryName)
@end

- ファイル名が(className + categoryName.hおよびclassName + categoryName.m)の2つのファイル.hおよび.mを取得します。

そして拡張の場合、あなたは得るでしょう

@interface className()
@end

-あなたは通りの名前で一つだけのファイルを取得しますclassName_extensionName.h

  • カテゴリでは、クラスを所有していませんが、拡張では所有しています。

5
@Prasanna:クラス拡張は.hの中だけではなく.Mファイルが付属しています
垂れ下がった

1
クラスの拡張だけでなく.M .hファイルが付属しています
Nishu_Priya

32
  1. カテゴリは、ソースコードが利用可能かどうかに関係なく、クラスにメソッドを追加する方法です。つまり、カテゴリを、のような基礎クラスNSStringや独自のカスタムクラスに追加できます。

    拡張機能は、コンパイラがソースコードと拡張機能を同時にコンパイルするため、ソースコードが利用可能なクラスにのみ追加できます。

  2. クラス拡張にはインスタンス変数とプロパティを追加できますが、カテゴリには追加できません。

  3. 拡張機能内の変数とメソッドは、継承されたクラスからもアクセスできません。

  4. カテゴリと拡張子はどちらも基本的に大きなコードベースを処理するように作られていますが、カテゴリは複数のソースファイルでクラスAPIを拡張する方法であり、拡張子はメインインターフェイスファイルの外部に必要なメソッドを追加する方法です。

  5. 同じクラスコードを異なる機能に応じて異なるソースファイルに分割する必要がある場合はcategoryを使用し、メインインターフェイスファイルの外部の既存のクラスに必要なメソッドを追加する必要がある場合はextensionを使用します。また、クラスで公に宣言されたインスタンス変数を変更する必要がある場合(たとえば、読み取り専用から読み取り/書き込み)、拡張機能で再宣言できます。


3
私は多くの答えを持つ5つの同様の質問を読みました、そしてこれは最高です。ありがとうございました!
ハニー

1
カテゴリにプロパティを追加することもできます。@Pebbyの回答を参照してください。
atulkhatri 2017

7

拡張機能:メソッドをプライベートにし、Appleクラスではなく独自のカスタムクラスのプロパティを追加します。

カテゴリ:プロパティではなく既存のクラスにメソッドを追加するには、カスタムクラスとAppleクラスの両方に使用できますNSString


シンプルでエレガント。続けてください
Abdul Yasin 2018年

3

カテゴリクラスでsetAssociatedプロパティを使用してプロパティを持つこともできます。

@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

参照:http//inchoo.net/dev-talk/ios-development/how-to-add-a-property-via-class-category/


2
@interface SomeClass ()


- (void) anAdditionalMethod;


@end

カテゴリを宣言する方法ではないと思います。カテゴリには名前が必要です

@interface SomeClass (XYZ)


- (void) anAdditionalMethod;


@end

例えば

@interface NSMutableArray (NSMutableArrayCreation)

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

@end

AppleによってNSMutableArray用に宣言されました


これは、カテゴリではなく、宣言と拡張の方法です-> @interface SomeClass()
ChavirA 2016

0

c#、java抽象クラスに類似したios拡張または
c#、javaクラス拡張に類似したインターフェース iosカテゴリー


4
「猫は虎に似ていて、盲人に答える」のようなあなたの答え。笑
Muruganandham K 2016

1
実際にはそうではありません。c#またはjavaを知っている場合、これは最も直接的で迅速な説明です。
add080bbA 2016

あまり説明的ではなく、質問にほとんど答えませんでした。
KVISH

0

カテゴリ

カテゴリは、多数のメソッドを含むファイルを作成するときに使用されるため、単一のクラスを異なるモジュールに分割する機能を提供します。また、カテゴリに変更が加えられても、コンパイラはプロジェクト全体をコンパイルするために時間を無駄にしません。 。カテゴリは、新しい変数またはプロパティを追加してその親クラスを検索することはできません。カテゴリ内のメソッドをオーバーライドすることはできますが、メソッドをさらにオーバーライドすることはできないため、お勧めできません。また、すべてのカテゴリに同じ階層レベルであるため、実行時に同じ親クラスに属する2つのカテゴリが存在する可能性があります。また、保護されたメソッドは、カテゴリを使用して作成できます。

拡張機能

拡張機能を使用すると、プロパティをオーバーライドしたり、既存の親クラスに新しいプロパティを追加したりできます。名前がなく、@ interface class()として表されるカテゴリと同じです。.mファイルが存在せず、拡張機能で宣言されたメソッドを実装する必要があります。親ファイルの@implementationで

このリンクでさらにヘルプ


0

これが私の理解です:

拡張機能は通常、独自の「カスタムクラス」に機能を追加するために使用されます」に。クラスの実装内で使用できるクラスインターフェイスを拡張するプライベートメソッドまたはプロパティを追加できます。

拡張機能は、クラスと同じファイル内に書き込まれます。したがって、String、Floatなどの事前定義されたタイプの拡張機能を作成することはできません。

一方、Categoriesを使用して、既存のクラスにメソッドを追加できます。例Stringクラスを拡張することで独自のメソッドを作成できます。カテゴリに追加のプロパティ作成できないことに注意してください。また、カテゴリの主な利点は、クラスが終了するファイルの外にある他のファイルにカテゴリを書き込むことができることです。

また、カテゴリを作成するときは、角かっこで囲んで名前を付ける必要があります。ただし、拡張子には名前は必要ありません。したがって、匿名カテゴリと呼ばれることもあります。


あなたは少し軌道に乗っていない。
Abdul Yasin 2018年

@iPhoneDeveloper事前定義されたタイプの拡張機能を記述できます。-このリンクをご確認くださいstackoverflow.com/a/33942484/2060508
yo2bh
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.