Pertanyaan Melewati Data antara Lihat Pengontrol


Saya baru untuk iOS dan Objective-C dan paradigma MVC keseluruhan dan saya terjebak dengan yang berikut:

Saya memiliki pandangan yang bertindak sebagai formulir entri data dan saya ingin memberi pengguna opsi untuk memilih beberapa produk. Produk terdaftar pada tampilan lain dengan UITableViewController dan saya telah mengaktifkan beberapa pilihan.

Pertanyaan saya adalah, bagaimana cara mentransfer data dari satu tampilan ke tampilan lainnya? Saya akan memegang pilihan di UITableView dalam larik, tetapi bagaimana cara saya meneruskannya kembali ke tampilan formulir entri data sebelumnya sehingga dapat disimpan bersama dengan data lain ke Data Inti pada penyerahan formulir?

Saya telah berselancar di sekitar dan melihat beberapa orang menyatakan array di delegasi aplikasi. Saya membaca sesuatu tentang Singletons tetapi tidak mengerti apa ini dan saya membaca sesuatu tentang membuat model data.

Apa cara yang tepat untuk melakukan ini dan bagaimana saya akan melakukannya?


1205
2018-03-06 12:43


asal


Jawaban:


Pertanyaan ini tampaknya sangat populer di sini di stackoverflow jadi saya pikir saya akan mencoba dan memberikan jawaban yang lebih baik untuk membantu orang memulai di dunia iOS seperti saya.

Saya harap jawaban ini cukup jelas untuk dipahami orang dan saya tidak melewatkan apa pun.

Melewati Data Maju

Melewatkan data ke pengontrol tampilan dari pengontrol tampilan lain. Anda akan menggunakan metode ini jika Anda ingin mengirimkan objek / nilai dari satu pengontrol tampilan ke pengontrol tampilan lain yang mungkin Anda dorong ke susunan navigasi.

Untuk contoh ini, kita akan memiliki ViewControllerA dan ViewControllerB

Untuk lulus a BOOL nilai dari ViewControllerA untuk ViewControllerB kami akan melakukan hal berikut.

  1. di ViewControllerB.h buat properti untuk BOOL

    @property (nonatomic, assign) BOOL isSomethingEnabled;
    
  2. di ViewControllerA Anda perlu menceritakannya ViewControllerB jadi gunakan

    #import "ViewControllerB.h"
    

    Lalu di mana Anda ingin memuat tampilan misalnya. didSelectRowAtIndex atau beberapa IBAction Anda perlu mengatur properti di ViewControllerB sebelum Anda mendorongnya ke nav stack.

    ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
    viewControllerB.isSomethingEnabled = YES;
    [self pushViewController:viewControllerB animated:YES];
    

    Ini akan diatur isSomethingEnabled di ViewControllerB untuk BOOL nilai YES.

Melewati Data Maju menggunakan Segmen

Jika Anda menggunakan Storyboard, Anda kemungkinan besar menggunakan segues dan akan membutuhkan prosedur ini untuk meneruskan data. Ini mirip dengan di atas tetapi alih-alih melewatkan data sebelum Anda mendorong pengontrol tampilan, Anda menggunakan metode yang disebut

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

Jadi untuk lulus BOOL dari ViewControllerA untuk ViewControllerB kami akan melakukan hal berikut:

  1. di ViewControllerB.h buat properti untuk BOOL

    @property (nonatomic, assign) BOOL isSomethingEnabled;
    
  2. di ViewControllerA Anda perlu menceritakannya ViewControllerB jadi gunakan

    #import "ViewControllerB.h"
    
  3. Buat segue dari ViewControllerA untuk ViewControllerB di storyboard dan berikan pengidentifikasi, dalam contoh ini kami akan menyebutnya "showDetailSegue"

  4. Selanjutnya kita perlu menambahkan metode ke ViewControllerA yang disebut ketika segue dilakukan, karena ini kita perlu mendeteksi yang disebut segue dan kemudian melakukan sesuatu. Dalam contoh kami, kami akan memeriksa "showDetailSegue" dan jika itu dilakukan, kami akan lulus BOOL nilai untuk ViewControllerB

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
        if([segue.identifier isEqualToString:@"showDetailSegue"]){
            ViewControllerB *controller = (ViewControllerB *)segue.destinationViewController;
            controller.isSomethingEnabled = YES;
        }
    }
    

    Jika Anda memiliki pandangan Anda tertanam dalam pengontrol navigasi Anda perlu mengubah metode di atas sedikit ke yang berikut

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
        if([segue.identifier isEqualToString:@"showDetailSegue"]){
            UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
            ViewControllerB *controller = (ViewControllerB *)navController.topViewController;
            controller.isSomethingEnabled = YES;
        }
    }
    

    Ini akan diatur isSomethingEnabled di ViewControllerB untuk BOOL nilai YES.

Melewati Data Kembali

Untuk mengembalikan data dari ViewControllerB untuk ViewControllerA Anda perlu menggunakan Protokol dan Delegasi atau Blok, yang terakhir dapat digunakan sebagai mekanisme yang digabungkan secara longgar untuk callback.

Untuk melakukan ini kami akan membuatnya ViewControllerA seorang delegasi dari ViewControllerB. Ini memungkinkan ViewControllerB untuk mengirim pesan kembali ke ViewControllerA memungkinkan kami mengirim data kembali.

Untuk ViewControllerA untuk menjadi delegasi ViewControllerB itu harus sesuai ViewControllerBprotokol yang harus kita tentukan. Ini memberitahu ViewControllerA metode mana yang harus diterapkan.

  1. Di ViewControllerB.h, dibawah #import, tetapi di atas @interface Anda tentukan protokolnya.

    @class ViewControllerB;
    
    @protocol ViewControllerBDelegate <NSObject>
    - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item;
    @end
    
  2. selanjutnya masih di ViewControllerB.h Anda perlu menyiapkan a delegate properti dan mensintesis di ViewControllerB.m

    @property (nonatomic, weak) id <ViewControllerBDelegate> delegate;
    
  3. Di ViewControllerB kami memanggil pesan di delegate saat kami memunculkan pengontrol tampilan.

    NSString *itemToPassBack = @"Pass this value back to ViewControllerA";
    [self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack];
    
  4. Itu untuk itu ViewControllerB. Sekarang di ViewControllerA.h, katakan ViewControllerA untuk mengimpor ViewControllerB dan sesuai dengan protokolnya.

    #import "ViewControllerB.h"
    
    @interface ViewControllerA : UIViewController <ViewControllerBDelegate>
    
  5. Di ViewControllerA.m terapkan metode berikut dari protokol kami

    - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item
    {
        NSLog(@"This was returned from ViewControllerB %@",item);
    }
    
  6. Sebelum mendorong viewControllerB untuk menavigasi tumpukan yang perlu kita ceritakan ViewControllerB bahwa ViewControllerA adalah delegasinya, kalau tidak kita akan mendapatkan kesalahan.

    ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
    viewControllerB.delegate = self
    [[self navigationController] pushViewController:viewControllerB animated:YES];
    

Referensi


1557
2018-03-16 11:39



Cepat

Ada banyak sekali penjelasan di sini dan di sekitar StackOverflow, tetapi jika Anda seorang pemula yang hanya mencoba mendapatkan sesuatu yang mendasar untuk bekerja, cobalah menonton tutorial YouTube ini (Itulah yang membantu saya untuk akhirnya memahami cara melakukannya).

Melewati data ke depan untuk Pengontrol Tampilan berikutnya

Berikut ini adalah contoh berdasarkan video. Idenya adalah untuk mengirim string dari bidang teks di First View Controller ke label di Pengontrol Tampilan Kedua.

enter image description here

Buat tata letak storyboard di Interface Builder. Untuk membuat segue, kamu saja Kontrol klik pada tombol dan seret ke Pengontrol Tampilan Kedua.

Pengontrol Tampilan Pertama

Kode untuk Pengontrol Tampilan Pertama adalah

import UIKit

class FirstViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!

    // This function is called before the segue
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        // get a reference to the second view controller
        let secondViewController = segue.destination as! SecondViewController

        // set a variable in the second view controller with the String to pass
        secondViewController.receivedString = textField.text!
    }

}

Pengontrol Tampilan Kedua

Dan kode untuk Pengontrol Tampilan Kedua adalah

import UIKit

class SecondViewController: UIViewController {

    @IBOutlet weak var label: UILabel!

    // This variable will hold the data being passed from the First View Controller
    var receivedString = ""

    override func viewDidLoad() {
        super.viewDidLoad()

        // Used the text from the First View Controller to set the label
        label.text = receivedString
    }

}

Jangan lupa

  • Hubungkan outlet untuk UITextField dan UILabel.
  • Setel Pengontrol Tampilan pertama dan kedua ke file Swift yang sesuai di IB.

Melewati data kembali ke View Controller sebelumnya

Untuk meneruskan data kembali dari pengontrol tampilan kedua ke pengontrol tampilan pertama, Anda gunakan protokol dan delegasi. Video ini berjalan sangat jelas meskipun dari proses itu:

Berikut ini adalah contoh berdasarkan video (dengan sedikit modifikasi).

enter image description here

Buat tata letak storyboard di Interface Builder. Sekali lagi, untuk membuat segue, Anda hanya Kontrol seret dari tombol ke Pengontrol Tampilan Kedua. Setel pengenal segue ke showSecondViewController. Juga, jangan lupa untuk menghubungkan outlet dan tindakan menggunakan nama-nama dalam kode berikut.

Pengontrol Tampilan Pertama

Kode untuk Pengontrol Tampilan Pertama adalah

import UIKit

class FirstViewController: UIViewController, DataEnteredDelegate {

    @IBOutlet weak var label: UILabel!

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showSecondViewController" {
            let secondViewController = segue.destination as! SecondViewController
            secondViewController.delegate = self
        }
    }

    func userDidEnterInformation(info: String) {
        label.text = info
    }
}

Perhatikan penggunaan kebiasaan kami DataEnteredDelegate protokol.

Pengawas dan Protokol Tampilan Kedua

Kode untuk pengontrol tampilan kedua adalah

import UIKit

// protocol used for sending data back
protocol DataEnteredDelegate: class {
    func userDidEnterInformation(info: String)
}

class SecondViewController: UIViewController {

    // making this a weak variable so that it won't create a strong reference cycle
    weak var delegate: DataEnteredDelegate? = nil

    @IBOutlet weak var textField: UITextField!

    @IBAction func sendTextBackButton(sender: AnyObject) {

        // call this method on whichever class implements our delegate protocol
        delegate?.userDidEnterInformation(info: textField.text!)

        // go back to the previous view controller
        _ = self.navigationController?.popViewController(animated: true)
    }
}

Perhatikan bahwa protocol berada di luar kelas View Controller.

Itu dia. Menjalankan aplikasi sekarang Anda harus dapat mengirim kembali data dari pengontrol tampilan kedua ke yang pertama.


131
2017-08-11 06:35



M dalam MVC adalah untuk "Model" dan dalam paradigma MVC peran kelas model adalah untuk mengelola data suatu program. Model adalah kebalikan dari pandangan - pandangan tahu bagaimana menampilkan data, tetapi tidak tahu apa yang harus dilakukan dengan data, sedangkan model tahu segalanya tentang cara bekerja dengan data, tetapi tidak ada cara untuk menampilkannya. Model dapat menjadi rumit, tetapi tidak harus - model untuk aplikasi Anda mungkin sesederhana susunan string atau kamus.

Peran pengontrol adalah untuk memediasi antara tampilan dan model. Oleh karena itu, mereka membutuhkan referensi ke satu atau lebih objek tampilan dan satu atau lebih objek model. Katakanlah model Anda adalah larik kamus, dengan masing-masing kamus mewakili satu baris di tabel Anda. Tampilan root untuk aplikasi Anda menampilkan tabel itu, dan mungkin bertanggung jawab untuk memuat larik dari file. Ketika pengguna memutuskan untuk menambahkan baris baru ke tabel, mereka mengetuk beberapa tombol dan pengontrol Anda membuat kamus baru (bisa diubah) dan menambahkannya ke array. Untuk mengisi baris, pengontrol membuat pengendali tampilan detail dan memberinya kamus baru. Pengontrol tampilan detail mengisi kamus dan mengembalikan. Kamus sudah menjadi bagian dari model, jadi tidak ada hal lain yang perlu terjadi.


118
2018-03-06 13:49



Ada berbagai cara agar data dapat diterima ke kelas yang berbeda di iOS. Sebagai contoh -

  1. Inisialisasi langsung setelah alokasi kelas lain.
  2. Delegasi - untuk meneruskan data kembali
  3. Pemberitahuan - untuk menyiarkan data ke banyak kelas sekaligus
  4. Menyimpan masuk NSUserDefaults - untuk mengaksesnya nanti
  5. Kelas Singleton
  6. Database dan mekanisme penyimpanan lainnya seperti plist, dll.

Tetapi untuk skenario sederhana yaitu menyerahkan nilai ke kelas yang berbeda yang alokasinya dilakukan di kelas saat ini, metode yang paling umum dan disukai adalah pengaturan langsung dari nilai setelah alokasi. Ini dilakukan sebagai berikut: -

Kami dapat memahaminya menggunakan dua pengontrol - Controller1 dan Controller2 

Misalkan di kelas Controller1 Anda ingin membuat objek Controller2 dan dorong dengan nilai String yang dilewatkan. Ini bisa dilakukan seperti ini: -

- (void)pushToController2 {

    Controller2 *obj = [[Controller2 alloc] initWithNib:@"Controller2" bundle:nil];
    [obj passValue:@"String"];
    [self pushViewController:obj animated:YES];
}

Dalam implementasi kelas Controller2 akan ada fungsi ini sebagai

@interface Controller2  : NSObject

@property (nonatomic , strong) NSString* stringPassed;

@end

@implementation Controller2

@synthesize stringPassed = _stringPassed;

- (void) passValue:(NSString *)value {

    _stringPassed = value; //or self.stringPassed = value
}

@end

Anda juga dapat langsung mengatur properti kelas Controller2 dengan cara yang sama seperti ini:

- (void)pushToController2 {

    Controller2 *obj = [[Controller2 alloc] initWithNib:@"Controller2" bundle:nil];
    [obj setStringPassed:@"String"];  
    [self pushViewController:obj animated:YES];
}

Untuk melewati beberapa nilai, Anda dapat menggunakan beberapa parameter seperti: -

Controller2 *obj = [[Controller2 alloc] initWithNib:@"Controller2" bundle:nil];
[obj passValue:@“String1” andValues:objArray withDate:date]; 

Atau jika Anda perlu melewatkan lebih dari 3 parameter yang terkait dengan fitur umum, Anda dapat menyimpan nilai ke kelas Model dan meneruskan model tersebut ke kelas berikutnya

ModelClass *modelObject = [[ModelClass alloc] init]; 
modelObject.property1 = _property1;
modelObject.property2 = _property2;
modelObject.property3 = _property3;

Controller2 *obj = [[Controller2 alloc] initWithNib:@"Controller2" bundle:nil];
[obj passmodel: modelObject];

Jadi, singkatnya jika Anda ingin -

1) set the private variables of the second class initialise the values by calling a custom function and passing the values.
2) setProperties do it by directlyInitialising it using the setter method.
3) pass more that 3-4 values related to each other in some manner , then create a model class and set values to its object and pass the object using any of the above process.

Semoga ini membantu


85
2018-04-08 10:24



Setelah penelitian lebih lanjut, tampaknya bahwa Protokol dan Delegasi adalah cara yang benar / lebih disukai Apple untuk melakukan hal ini.

Saya akhirnya menggunakan contoh ini

Berbagi data antara pengontrol tampilan dan objek lainnya @ SDK Pengembang iPhone

Bekerja dengan baik dan memungkinkan saya untuk mengirim string dan array maju dan mundur antara pandangan saya.

Terima kasih atas seluruh bantuan Anda


74
2018-03-13 21:20



Saya menemukan versi yang paling sederhana dan paling elegan dengan melewati blok. Mari kita beri nama pengendali tampilan yang menunggu data yang dikembalikan sebagai "A" dan mengembalikan pengendali tampilan sebagai "B". Dalam contoh ini kita ingin mendapatkan 2 nilai: pertama dari Type1 dan second dari Type2.

Dengan asumsi kami menggunakan Storyboard, pengontrol pertama menetapkan blok panggilan balik, misalnya selama persiapan segue:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.destinationViewController isKindOfClass:[BViewController class]])
    {
        BViewController *viewController = segue.destinationViewController;

        viewController.callback = ^(Type1 *value1, Type2 *value2) {
            // optionally, close B
            //[self.navigationController popViewControllerAnimated:YES];

            // let's do some action after with returned values
            action1(value1);
            action2(value2);
        };

    }
}

dan "B" view controller harus menyatakan properti callback, BViewController.h:

// it is important to use "copy"
@property (copy) void(^callback)(Type1 *value1, Type2 *value2);

Daripada dalam file implementasi BViewController.m setelah kami memiliki nilai yang diinginkan untuk mengembalikan callback kami harus dipanggil:

if (self.callback)
    self.callback(value1, value2);

Satu hal yang perlu diingat adalah bahwa penggunaan blok sering perlu mengelola referensi yang kuat dan __weak seperti dijelaskan sini


59
2017-10-14 18:11



Ada beberapa informasi bagus di banyak jawaban yang diberikan, tetapi tidak ada yang menjawab pertanyaan sepenuhnya.

Pertanyaannya menanyakan tentang melewatkan informasi antara pengontrol tampilan. Contoh spesifik yang diberikan menanyakan tentang menyampaikan informasi di antara pandangan, tetapi mengingat kebaruan yang dinyatakan sendiri ke iOS, poster asli mungkin berarti antara viewControllers, bukan antara tampilan (tanpa keterlibatan dari ViewControllers). Tampaknya semua jawaban fokus pada dua pengontrol tampilan, tetapi bagaimana jika aplikasi berevolusi perlu melibatkan lebih dari dua pengontrol tampilan dalam pertukaran informasi?

Poster asli juga bertanya tentang Singletons dan penggunaan AppDelegate. Pertanyaan-pertanyaan ini perlu dijawab.

Untuk membantu orang lain melihat pertanyaan ini, yang menginginkan jawaban lengkap, saya akan berusaha menyediakannya.

Skenario Aplikasi

Alih-alih memiliki diskusi abstrak yang sangat hipotetis, itu membantu untuk memiliki aplikasi konkret dalam pikiran. Untuk membantu mendefinisikan situasi dua-view-controller dan situasi yang lebih dari dua-view-controller, saya akan mendefinisikan dua skenario aplikasi konkret.

Skenario satu: maksimum dua pengontrol tampilan yang perlu membagikan informasi. Lihat diagram satu.

diagram of original problem

Ada dua pengontrol tampilan dalam aplikasi. Ada ViewControllerA (Form Data Entry), dan Lihat Controller B (Daftar Produk). Item yang dipilih dalam daftar produk harus sesuai dengan item yang ditampilkan dalam kotak teks dalam formulir entri data. Dalam skenario ini, ViewControllerA dan ViewControllerB harus berkomunikasi secara langsung satu sama lain dan tidak ada pengendali tampilan lainnya.

Skenario dua: lebih dari dua pengontrol tampilan perlu berbagi informasi yang sama. Lihat diagram dua.

home inventory application diagram

Ada empat pengontrol tampilan dalam aplikasi. Ini adalah aplikasi berbasis tab untuk mengelola persediaan rumah. Tiga pengontrol tampilan menyajikan pandangan berbeda yang difilter dari data yang sama:

  • ViewControllerA - Barang Mewah
  • ViewControllerB - Barang Tidak Tertanggung
  • ViewControllerC - Seluruh Inventaris Rumah
  • ViewControllerD - Tambah Form Barang Baru

Setiap kali setiap item dibuat atau diedit, itu juga harus disinkronkan dengan pengontrol tampilan lainnya. Sebagai contoh, jika kita menambahkan perahu di ViewControllerD, tetapi belum diasuransikan, maka perahu harus muncul ketika pengguna pergi ke ViewControllerA (Barang Mewah), dan juga ViewControllerC (Seluruh Inventaris Rumah), tetapi tidak ketika pengguna pergi ke ViewControllerB (Barang Tidak Tertanggung). Kita perlu memperhatikan tidak hanya menambahkan item baru, tetapi juga menghapus item (yang mungkin diizinkan dari salah satu dari empat pengendali tampilan), atau mengedit item yang sudah ada (yang mungkin diizinkan dari "Tambahkan Formulir Item Baru", mengubah yang sama untuk mengedit).

Karena semua pengontrol tampilan perlu berbagi data yang sama, keempat pengontrol tampilan harus tetap bersinkronisasi, dan oleh karena itu perlu ada semacam komunikasi ke semua pengontrol tampilan lainnya, setiap kali pengontrol tampilan tunggal mengubah data yang mendasarinya. Seharusnya cukup jelas bahwa kita tidak ingin setiap pengontrol tampilan berkomunikasi langsung dengan masing-masing pengontrol tampilan lain dalam skenario ini. Jika tidak jelas, pertimbangkan jika kami memiliki 20 pengontrol tampilan berbeda (bukan hanya 4). Seberapa sulit dan rawan kesalahan untuk memberi tahu masing-masing dari 19 pengontrol tampilan lainnya kapan saja satu pengendali tampilan melakukan perubahan?

Solusi: Delegasi dan Pola Observer, dan Singletons

Dalam skenario pertama, kami memiliki beberapa solusi yang layak, sebagaimana telah diberikan jawaban lain

  • segues
  • delegasi
  • pengaturan properti pada pengendali tampilan secara langsung
  • NSUserDefaults (sebenarnya pilihan yang buruk)

Dalam skenario dua, kami memiliki solusi lain yang dapat dijalankan:

  • Pola Pengamat
  • Singletons

SEBUAH tunggal adalah sebuah instance dari sebuah kelas, contoh itu adalah satu-satunya contoh yang ada selama masa hidupnya. Seorang tunggal mendapatkan namanya dari fakta bahwa itu adalah contoh tunggal. Biasanya pengembang yang menggunakan lajang memiliki metode kelas khusus untuk mengaksesnya.

+ (HouseholdInventoryManager*) sharedManager; {
    static dispatch_once_t onceQueue;
    static HouseholdInventoryManager* _sharedInstance;

    // dispatch_once is guaranteed to only be executed once in the
    // lifetime of the application
    dispatch_once(&onceQueue, ^{
        _sharedInstance = [[self alloc] init];
    });
    return _sharedInstance;
}

Sekarang kita mengerti apa itu singleton, mari kita diskusikan bagaimana seorang tunggal cocok dengan pola pengamat. Pola pengamat digunakan untuk satu objek untuk merespon perubahan oleh objek lain. Dalam skenario kedua, kami memiliki empat pengontrol tampilan berbeda, yang semuanya ingin tahu tentang perubahan pada data yang mendasarinya. "Data yang mendasari" harus milik satu contoh, tunggal. "Tahu tentang perubahan" dilakukan dengan mengamati perubahan yang dilakukan pada orang tunggal.

Aplikasi inventaris rumah akan memiliki satu instance dari kelas yang dirancang untuk mengelola daftar item inventaris. Manajer akan mengatur koleksi barang-barang rumah tangga. Berikut ini adalah definisi kelas untuk pengelola data:

#import <Foundation/Foundation.h>

@class JGCHouseholdInventoryItem;

@interface HouseholdInventoryManager : NSObject
/*!
 The global singleton for accessing application data
 */
+ (HouseholdInventoryManager*) sharedManager;


- (NSArray *) entireHouseholdInventory;
- (NSArray *) luxuryItems;
- (NSArray *) nonInsuredItems;

- (void) addHouseholdItemToHomeInventory:(JGCHouseholdInventoryItem*)item;
- (void) editHouseholdItemInHomeInventory:(JGCHouseholdInventoryItem*)item;
- (void) deleteHoueholdItemFromHomeInventory:(JGCHouseholdInventoryItem*)item;
@end

Ketika koleksi item persediaan rumah berubah, pengontrol tampilan perlu dibuat sadar akan perubahan ini. Definisi kelas di atas tidak membuatnya jelas bagaimana ini akan terjadi. Kita harus mengikuti pola pengamat. Pengontrol tampilan harus secara resmi mengamati sharedManager. Ada dua cara untuk mengamati objek lain:

  • Key-Value-Observing (KVO)
  • NSNotificationCenter.

Dalam skenario dua, kami tidak memiliki satu pun properti dari HouseholdInventoryManager yang dapat diamati menggunakan KVO. Karena kita tidak memiliki satu properti yang mudah diamati, pola pengamat, dalam hal ini, harus diimplementasikan menggunakan NSNotificationCenter. Masing-masing dari empat pengendali tampilan akan berlangganan pemberitahuan, dan sharedManager akan mengirim pemberitahuan ke pusat pemberitahuan jika diperlukan. Manajer inventaris tidak perlu mengetahui apa pun tentang pengontrol tampilan atau contoh kelas lain mana pun yang mungkin tertarik mengetahui kapan pengumpulan item inventaris berubah; NSNotificationCenter menangani detail penerapan ini. The View Controllers cukup berlangganan notifikasi, dan pengelola data cukup memposting pemberitahuan.

Banyak programmer pemula mengambil keuntungan dari fakta bahwa selalu ada satu Delegasi Aplikasi dalam seumur hidup aplikasi, yang dapat diakses secara global. Pemrogram pemula menggunakan fakta ini untuk menjejalkan objek dan fungsi ke dalam appDelegate sebagai kemudahan untuk mengakses dari tempat lain dalam aplikasi. Hanya karena AppDelegate adalah tunggal tidak berarti harus mengganti semua lajang lainnya. Ini adalah praktik yang buruk karena menempatkan terlalu banyak beban pada satu kelas, melanggar praktik berorientasi objek yang baik. Setiap kelas harus memiliki peran yang jelas yang mudah dijelaskan, seringkali hanya dengan nama kelas.

Setiap kali Delegasi Aplikasi Anda mulai membengkak, mulailah untuk menghapus fungsionalitas ke dalam lajang. Misalnya, Tumpukan Data Inti tidak boleh ditinggalkan di AppDelegate, tetapi sebaliknya harus diletakkan di kelasnya sendiri, kelas coreDataManager.

Referensi


46
2018-04-05 22:04