Skip to content
This repository has been archived by the owner on Jun 20, 2023. It is now read-only.

9.2 クラス設計 2

Koya Tamura edited this page May 20, 2013 · 11 revisions

引き続きクラス設計について説明します。

Objective-C における抽象クラス

9.1 で例として挙げた仕様がありました。

  • ファーストビューので、曜日ごとに違う画像を表示したい
  • その画像をタップした際の画面遷移やアクションが画像によってことなる

この仕様が画像では無く、様々な種類のビューをオーバーレイし、×ボタンを押すと閉じることが出来るように変更したいとします。

abstractClass1

この場合は、一つのカスタムビュークラスでテキストビューやイメージビューなどのサブビューを条件分岐で表示非表示にしがちです。しかし、そうしてしまうとコードにレイアウトのコードが増えたり、ビューの種類が増えてきた場合に条件分岐がさらに多くなり対応が難しくなります。

こういったケースでは抽象クラスを使うと上記の問題は解決できます。

ポイント Objective-C では、抽象クラスを作成する言語的機能(Java の abstract 修飾子など)は存在しません。よって、抽象クラスとして作成したクラスのインスタンスも生成可能です。NSObject クラスのインスタンスが生成可能なように、Objective-C では抽象クラスの扱いに関しては開発者側で行う必要があります。

上記の例では抽象クラスを作成し、そのサブクラスで適宜必要なコンポーネントとレイアウトの実装を行うと良いでしょう。

abstractClass1

では実際に実装していきましょう。ここでは YES/NO のボタンを設置するカスタムビュー MixiDailyChoiceView を作成していきます。

抽象クラス MixiDailyView では xib ファイルは作成せず、.h .m ファイルだけ作成します。

ヘッダーでは、サブクラスの delegate method 全てを含めた delegate protocol を宣言しておきます。全てのサブクラスで実装する必要のある delegate method は @required で、サブクラスごとに実装が必要なものに関しては @optional にしておけば必要に応じて delegate 先で実装できます。

MixiDailyView.h

@protocol MixiDailyViewDelegate <NSObject>

@required
-(void)dailyViewDidPressCloseButton;

@optional
-(void)dailyViewDidPressYesButton;
-(void)dailyViewDidPressNoButton;

@end

@interface MixiDailyView : UIView

@property (nonatomic, weak) IBOutlet UILabel *titleLabel;
@property (nonatomic, weak) IBOutlet UIButton *closeButton;
@property (nonatomic, weak) IBOutlet UILabel *dateLabel;
@property (nonatomic, weak) id delegate;

+(MixiDailyView *)dailyView;
-(IBAction)pressCloseButton:(id)sender;

@end

MixiDailyView.m

#import "MixiDailyView.h"

@implementation MixiDailyView


-(void)pressCloseButton:(id)sender
{
    if ([_delegate respondsToSelector:@selector(dailyViewDidPressCloseButton)]) {
        [_delegate dailyViewDidPressCloseButton];
    }
}

@end

実装クラスである MixiDailyChoiceView では .h, .m に加えて .xib まで作成して実装します。

MixiDailyChoiceView.h

#import "MixiDailyView.h"

@interface MixiDailyChoiceView : MixiDailyView

- (IBAction)pressYesButton:(id)sender;
- (IBAction)pressNoButton:(id)sender;

@end

MixiDailyChoiceView.m

#import "MixiDailyChoiceView.h"

@implementation MixiDailyChoiceView

+(MixiDailyView *)dailyView
{
    NSArray *topLevelViews = [[NSBundle mainBundle] loadNibNamed:@"MixiDailyChoiceView"
                                                           owner:self
                                                         options:nil];
    MixiDailyChoiceView *dailyChoiceView = topLevelViews[0];
    return dailyChoiceView;
}

- (IBAction)pressYesButton:(id)sender
{
    if([self.delegate respondsToSelector:@selector(dailyViewDidPressYesButton)]){
        [self.delegate dailyViewDidPressYesButton];
    }
}

- (IBAction)pressNoButton:(id)sender
{
    if([self.delegate respondsToSelector:@selector(dailyViewDidPressNoButton)]){
        [self.delegate dailyViewDidPressNoButton];
    }
}

@end

MixiDailyChoiceView.xib

MixiDailyChoiceView-xib

インスタンスを生成して表示させてみましょう。

MixiViewController.h

#import <UIKit/UIKit.h>
#import "MixiDailyChoiceView.h"

@interface MixiViewController : UIViewController<MixiDailyViewDelegate>

@end

MixiViewController.m

#import "MixiViewController.h"

@interface MixiViewController ()

@property (nonatomic, strong) MixiDailyView *dailyView;

@end

@implementation MixiViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    _dailyView = [MixiDailyChoiceView dailyView];
    _dailyView.center = self.view.center;
    _dailyView.delegate = self;
    [self.view addSubview:_dailyView];
}

-(void)dailyViewDidPressCloseButton
{
    [_dailyView removeFromSuperview];
}

-(void)dailyViewDidPressYesButton
{
    //do something
    NSLog(@"Yes");
}

-(void)dailyViewDidPressNoButton
{
    //do something
    NSLog(@"No");
}

@end

MixiDailyChoiceView

Singleton インスタンス

アプリケーション内で一つだけインスタンスを存在させたい場合、Singlton パターンを使って実装します。Cocoa API では [NSUserDefaults standerdDefaults] [NSNotificationCenter defaultCenter] などで実現されています。その実装方法は以下のようになります。

MixiSharedObject.h

#import <Foundation/Foundation.h>

@interface MixiSharedObject : NSObject

+(MixiSharedObject *)sharedInstance;

-(void)doSomthing;

@end

MixiSharedObject.m

#import "MixiSharedObject.h"

@implementation MixiSharedObject

+(MixiSharedObject *)sharedInstance
{
    static MixiSharedObject *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[MixiSharedObject alloc] init];
    });
    return sharedInstance;
}

-(void)doSomthing
{
    //doSomething
}

@end

この実装により、どこからインスタンス生成を行ってもアプリケーション上では一つのインスタンスしか存在しないようになります。 試しにインスタンス生成を複数回行ったとします。

_array = [NSMutableArray array];
for (NSInteger i = 0; i < 10; i++) {
    [_array addObject:[MixiSharedObject sharedInstance]];
}

instruments で allocation を見るてもインスタンスが一つだけ存在していることが分かります。(instruments に関しては 10 章で解説します)

instruments

はじめに

  1. iOSについて

  2. Xcode最初のステッフ

  3. 導入

  4. Objective C の基礎

  5. メモリ管理

  6. 1.3 UIViewController1 UIViewController のカスタマイズ(xib, autoresizing)

  7. 1.3 UIViewController1 UIViewController のカスタマイズ(storyboard)

  8. UIViewController2 - ModalViewController

  9. UIViewController2 - ModalViewController(storyboard)

  10. UIViewController3 - ライフサイクル

  11. HomeWork 1 Objective C の基本文法

  12. HomeWork 2 UIViewControllerとModalViewController

  13. HomeWork 3 UIViewController + Animation

  14. UIKit 1 - container, rotate-

  15. UINavigationController

  16. UITabController

  17. Custom Container View Controller

  18. Supporting Multiple Interface Orientations

  19. HomeWork 1 - タブバーからモーダルビューを表示する

  20. HomeWork 2 - NavigationController

  21. HomeWork 2.3 デバイスことに回転対応

  22. UIKit 2- UIView -

  23. UIView

  24. UIView のカスタマイズ

  25. UIView Animation

  26. HomeWork 1 - UIScrollView

  27. UIKit 3 - table view -

  28. UITableView について

  29. UITableViewとNavigationController

  30. custom UITableViewCell の作成

  31. UITableViewのその他のオプション、カスタマイズ

  32. HomeWork 1 - Dynamic height with a custom uitableviewcell

  33. UIKit 4 - image and text -

  34. UIImagePickerController

  35. Assets Library

  36. UITextFiled, UITextView

  37. KeyboardNotification

  38. Homework 1 - フォトの複数枚選択

  39. ネットワーク処理

  40. NSURLConnection

  41. JSONのシリアライズとデシリアライズ

  42. UIWebView

  43. ローカルキャッシュと通知

  44. NSUserDefaults, Settings Bundle

  45. NSFileManager

  46. Key Value Observing

  47. NSNotification、NSNotificationCenter を用いた通知

  48. UILocalNotification

  49. Blocks, GCD

  50. Blocks

  51. GCD

  52. 【演習】GCD,-Blocksを用いたHTTPリクエストマネージャの作成

  53. 設計とデザインパターン

  54. クラス設計 1

  55. クラス設計 2

  56. [クラス設計演習] (https://github.com/mixi-inc/iOSTraining/wiki/9.3-%E3%82%AF%E3%83%A9%E3%82%B9%E8%A8%AD%E8%A8%88%E6%BC%94%E7%BF%92)

  57. 開発ツール

  58. Instruments, デバッガ

  59. CocoaPods

  60. テスト

  61. iOS開発におけるテスト

  62. GHUnit

  63. Kiwi

  64. KIF

  65. In-App Purchase

  66. In-App Purchase

  67. 付録

  68. Tips of Xcode

  69. Auto Layout 入門

  70. Auto Layout ドリル

Edit sidebar

Clone this wiki locally