Indonesian (Bahasa Indonesia) translation by Nurul Fatimah (you can also view the original English article)
Multi-tasking mencegah aplikasi dari freezing. Dalam sebagian besar bahasa pemrograman, pencapaian ini agak sedikit rumit, tetapi kelas NSOperationQueue di iOS membuatnya mudah!
Tutorial ini akan menunjukkan bagaimana menggunakan NSOperationQueue kelas. Sebuah objek NSOperationQueue adalah suatu antrian yang menangani objek dari jenis yang kelas NSOperation. Objek NSOperation, hanya diungkapkan, mewakili satu tugas, termasuk data dan kode yang terkait dengan tugas. NSOperationQueue menangani dan mengelola eksekusi semua objek NSOperation (tugas) yang telah ditambahkan ke dalamnya. Eksekusi berlangsung dengan rangkaian utama aplikasi. Ketika sebuah objek NSOperation ditambahkan ke antrian, ia dieksekusi segera dan tidak meninggalkan antrian sampai selesai. Tugas dapat dibatalkan, tetapi tidak dihapus dari antrean sampai selesai. Kelas NSOperation adalah satu abstrak sehingga tidak bisa digunakan secara langsung dalam program. Sebaliknya, ada dua subkelas disediakan, kelas NSInvocationOperation dan kelas NSBlockOperation. Saya akan menggunakan yang pertama dalam tutorial ini.
Contoh proyek
Inilah tujuan untuk tutorial ini: untuk setiap rangkaian tambahan kita ingin aplikasi kita membuat objek NSInvocationOperation (NSOperation). Kita akan menambahkan setiap objek menjadi NSOperationQueue dan kemudian kita selesai. Antrean mengambil alih segalanya dan aplikasi bekerja tanpa freezing. Untuk menunjukkan dengan jelas penggunaan kelas yang saya sebutkan di atas, kita akan membuat proyek sampel (sederhana) di mana, selain dari rangkaian utama aplikasi, kita akan memiliki dua rangkaian lagi yang berjalan bersamanya. Pada utas rangkaian, loop akan berjalan dari 1 hingga 10.000.000 dan setiap 100 langkah label akan diperbarui dengan nilai counter loop. Pada rangkaian kedua, background sebuah label akan mengisi dengan warna kustom. Proses ini akan mengambil tempat di dalam lingkaran dan itu akan dijalankan lebih dari sekali. Jadi kita akan memiliki sesuatu seperti rotator warna. Pada saat yang sama, nilai-nilai RGB warna background custom dengan nilai konter loop akan ditampilkan di samping label. Akhirnya, kita akan menggunakan tiga tombol untuk mengubah warna background pemandangan yang pada rangkaian. Tugas ini tidak akan dijalankan secara bersamaan tanpa multi-tasking. Berikut ini adalah hasil akhirnya:

Langkah 1: Buat Proyek
Mari kita mulai dengan menciptakan proyek. Buka Xcode dan buat Single View Application baru.



Klik Next dan menetapkan nama untuk proyek. Saya menamakannya ThreadingTestApp. Anda dapat menggunakan yang sama atau nama lain yang Anda suka.



Berikutnya. Selesaikan proyek penciptaan.



Langkah 2: Setup Interface
Klik pada file ViewController.xib
untuk mengungkapkan Builder interface. Tambahkan kontrol berikut untuk membuat interface seperti gambar berikutnya:



- UINavigationBar
- Frame (x, y, W, H): 0, 0, 320, 44
- Tintcolor: Warna hitam
- Title: "Simple Multi-Threading Demo"
- UILabel
- Frame (x, y, W, H): 20, 59, 280, 21
- Text: "Counter at Thread #1"
- UILabel
- Frame (x, y, W, H): 20, 88, 280, 50
- Background color: Warna light gray
- Text color: Warna dark gray
- Text: -
- UILabel
- Frame (x, y, W, H): 20, 154, 280, 21
- Text: "Random Color Rotator at Thread #2"
- UILabel
- Frame (x, y, W, H): 20, 183, 100, 80
- Background color: Warna light gray
- Text: -
- UILabel
- Frame (x, y, W, H): 128, 183, 150, 80
- Text: -
- UILabel
- Frame (x, y, W, H): 20, 374, 280, 21
- Text: "Background Color at Main Thread"
- UIButton
- Frame (x, y, W, H): 20, 403, 73, 37
- Title: "Color #1"
- UIButton
- Frame (x, y, W, H): 124, 403, 73, 37
- Title: "Color #2"
- UIButton
- Frame (x, y, W, H): 228, 403, 73, 37
- Title: "Color #3"
Untuk UILabel terakhir dan tiga UIButtons, atur nilai Autosizing ke Kiri - Bawah untuk membuat interface terlihat bagus pada iPhone 4 / 4S dan iPhone 5, seperti gambar berikutnya:



Langkah 3: Properti IBOutlet dan Metode IBAction
Pada langkah berikutnya, kita akan membuat properti IBOutlet dan metode IBAction yang diperlukan untuk membuat contoh aplikasi kita berfungsi. Untuk membuat properti dan metode baru, dan hubungkan ke kontrol Anda saat menjadi Interface Builder, klik tombol tengah tombol Editor di toolbar Xcode untuk membuka Assistant Editor:

Kontrol tidak setiap kebutuhan properti outlet. Kita hanya akan menambahkan satu untuk UILabel 3, 5, dan 6 (sesuai urutan yang tercantum pada langkah 2), bernama label1, label2, dan label3.
Untuk memasukkan properti outlet baru, Control + Klik (Klik kanan) pada label > Klik pada Outlet Referensi Baru > Seret dan Turunkan ke Asisten Editor. Setelah itu, tentukan nama untuk properti baru, seperti pada gambar berikut:
Memasukkan properti IBOutlet baru
Menetapkan nama properti IBOutlet
Ulangi proses di atas tiga kali untuk menghubungkan ketiga UILabel ke properti. Di dalam file ViewController.h
Anda, Anda memiliki properti ini yang dinyatakan:
@property (retain, nonatomic) IBOutlet UILabel *label1; @property (retain, nonatomic) IBOutlet UILabel *label2; @property (retain, nonatomic) IBOutlet UILabel *label3;
Sekarang tambahkan metode IBAction untuk ketiga UIButtons. Masing-masing tombol akan mengubah warna background tampilan. Untuk memasukkan metode IBAction baru, Control + Click (Klik kanan) pada UIButton > Klik pada Touch Up Inside > Drag dan Drop ke Asisten Editor. Setelah itu tentukan nama untuk metode baru. Lihatlah gambar berikut dan cuplikan berikutnya untuk nama metode:



Memasukkan metode IBAction baru



Menetapkan nama metode IBAction
Sekali lagi, ulangi proses di atas tiga kali untuk menghubungkan setiap UIButton ke metode tindakan. File ViewController.h
sekarang harus berisi ini:
- (IBAction)applyBackgroundColor1; - (IBAction)applyBackgroundColor2; - (IBAction)applyBackgroundColor3;
Properti IBOutlet dan metode IBAction sudah siap. Kita sekarang dapat mulai pengkodean.
Langkah 4: Objek NSOperationQueue dan Deklarasi Metode Tugas-Terkait yang Diperlukan
Salah satu tugas terpenting yang harus kita lakukan adalah mendeklarasikan objek NSOperationQueue
(antrian operasi), yang akan digunakan untuk menjalankan tugas kami di utas sekunder. Buka file ViewController.h
dan tambahkan konten berikut tepat setelah header @interface
(jangan lupa tanda kurung kurawal):
@interface ViewController : UIViewController{ NSOperationQueue *operationQueue; }
Juga, setiap tugas harus memiliki setidaknya satu metode yang berisi kode yang akan dijalankan bersamaan dengan rangkaian utama. Menurut deskripsi pendahuluan, tugas pertama metode akan diberi nama counterTask
dan yang kedua akan diberi nama colorRotatorTask
:
-(void)counterTask; -(void)colorRotatorTask;
Itulah semua yang kita butuhkan. File ViewController.h
kita akan terlihat seperti ini:
@interface ViewController : UIViewController{ NSOperationQueue *operationQueue; } @property (retain, nonatomic) IBOutlet UILabel *label1; @property (retain, nonatomic) IBOutlet UILabel *label2; @property (retain, nonatomic) IBOutlet UILabel *label3; - (IBAction)applyBackgroundColor1; - (IBAction)applyBackgroundColor2; - (IBAction)applyBackgroundColor3; -(void)counterTask; -(void)colorRotatorTask; @end
Mari kita lanjutkan ke implementasi.
Langkah 5: implementasi
Kita hampir selesai. Kita telah mengatur interface, membuat semua koneksi yang diperlukan, menyatakan IBAction yang diperlukan dan metode lain, dan membangun basis. Sekarang saatnya untuk membangunnya.
Buka file ViewController.m
dan masuk ke metode viewDidLoad
. Bagian terpenting dari tutorial ini akan berlangsung di sini. Kita akan membuat instance NSOperationQueue
baru dan dua objek NSOperation (NSInvocationOperation)
. Objek-objek ini akan merangkum kode dari dua metode yang sebelumnya kita nyatakan dan kemudian mereka akan dieksekusi sendiri oleh NSOperationQueue
. Berikut ini kodenya:
- (void)viewDidLoad { [super viewDidLoad]; // Create a new NSOperationQueue instance. operationQueue = [NSOperationQueue new]; // Create a new NSOperation object using the NSInvocationOperation subclass. // Tell it to run the counterTask method. NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(counterTask) object:nil]; // Add the operation to the queue and let it to be executed. [operationQueue addOperation:operation]; [operation release]; // The same story as above, just tell here to execute the colorRotatorTask method. operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(colorRotatorTask) object:nil]; [operationQueue addOperation:operation]; [operation release]; }
Seluruh proses ini sangat sederhana. Setelah membuat instance NSOperationQueue
, kita membuat objek NSInvocationOperation (operasi). Kita mengatur metode pemilihnya (kode yang diinginkan dieksekusi pada utas yang terpisah), dan kemudian kita menambahkannya ke antrian. Setelah memasuki antrean segera mulai berjalan. Setelah itu objek operasi dapat dilepaskan, karena antrean bertanggung jawab untuk menanganinya mulai dari sekarang. Dalam hal ini kita membuat objek lain dan kita akan menggunakannya dengan cara yang sama untuk tugas kedua (colorRotatorTask).
Tugas kita berikutnya adalah mengimplementasikan dua metode selektor. Mari kita mulai dengan menulis metode counterTask
. Ini akan berisi for
loop yang akan berjalan untuk sejumlah besar iterasi dan setiap 100 langkah teks label1
akan diperbarui dengan nilai counter iterasi saat ini (i
). Kode ini sederhana, jadi di sini adalah segalanya:
-(void)counterTask{ // Make a BIG loop and every 100 steps let it update the label1 UILabel with the counter's value. for (int i=0; i<10000000; i++) { if (i % 100 == 0) { // Notice that we use the performSelectorOnMainThread method here instead of setting the label's value directly. // We do that to let the main thread to take care of showing the text on the label // and to avoid display problems due to the loop speed. [label1 performSelectorOnMainThread:@selector(setText:) withObject:[NSString stringWithFormat:@"%d", i] waitUntilDone:YES]; } } // When the loop gets finished then just display a message. [label1 performSelectorOnMainThread:@selector(setText:) withObject:@"Thread #1 has finished." waitUntilDone:NO]; }
Harap dicatat bahwa ini direkomendasikan sebagai praktik terbaik (bahkan oleh Apple) untuk melakukan pembaruan visual apa pun pada antarmuka menggunakan rangkaian utama dan bukan dengan melakukannya langsung dari utas sekunder. Oleh karena itu, penggunaan metode performSelectorOnMainThread
diperlukan dalam kasus seperti ini.
Sekarang mari kita menerapkan metode colorRotatorTask
:
-(void)colorRotatorTask{ // We need a custom color to work with. UIColor *customColor; // Run a loop with 500 iterations. for (int i=0; i<500; i++) { // Create three float random numbers with values from 0.0 to 1.0. float redColorValue = (arc4random() % 100) * 1.0 / 100; float greenColorValue = (arc4random() % 100) * 1.0 / 100; float blueColorValue = (arc4random() % 100) * 1.0 / 100; // Create our custom color. Keep the alpha value to 1.0. customColor = [UIColor colorWithRed:redColorValue green:greenColorValue blue:blueColorValue alpha:1.0]; // Change the label2 UILabel's background color. [label2 performSelectorOnMainThread:@selector(setBackgroundColor:) withObject:customColor waitUntilDone:YES]; // Set the r, g, b and iteration number values on label3. [label3 performSelectorOnMainThread:@selector(setText:) withObject:[NSString stringWithFormat:@"Red: %.2f\nGreen: %.2f\nBlue: %.2f\Iteration #: %d", redColorValue, greenColorValue, blueColorValue, i] waitUntilDone:YES]; // Put the thread to sleep for a while to let us see the color rotation easily. [NSThread sleepForTimeInterval:0.4]; } // Show a message when the loop is over. [label3 performSelectorOnMainThread:@selector(setText:) withObject:@"Thread #2 has finished." waitUntilDone:NO]; }
Anda dapat melihat bahwa kita menggunakan metode performSelectorOnMainThread
di sini juga. Langkah selanjutnya adalah [NSThread sleepForTimeInterval: 0,4];
perintah, yang digunakan untuk menyebabkan beberapa penundaan singkat (0,4 detik) dalam setiap eksekusi loop. Meskipun tidak perlu menggunakan metode ini, lebih baik untuk menggunakannya di sini untuk memperlambat perubahan warna background label2
UILabel (rotator warna). Selain itu di setiap loop kita membuat nilai acak untuk warna merah, hijau, dan biru. Kita kemudian menetapkan nilai-nilai ini untuk menghasilkan warna kustom dan mengaturnya sebagai warna backgorund di label2
UILabel.
Pada titik ini dua tugas yang akan dieksekusi pada saat yang sama dengan utas utama sudah siap. Mari terapkan ketiga metode IBAction (sangat mudah) dan kemudian kita siap untuk lanjut. Seperti yang telah saya sebutkan, ketiga UIButtons akan mengubah warna latar belakang tampilan, dengan tujuan akhir untuk menunjukkan bagaimana utas utama dapat berjalan di samping dua tugas lainnya. Ini dia:
- (IBAction)applyBackgroundColor1 { [self.view setBackgroundColor:[UIColor colorWithRed:255.0/255.0 green:204.0/255.0 blue:102.0/255.0 alpha:1.0]]; } - (IBAction)applyBackgroundColor2 { [self.view setBackgroundColor:[UIColor colorWithRed:204.0/255.0 green:255.0/255.0 blue:102.0/255.0 alpha:1.0]]; } - (IBAction)applyBackgroundColor3 { [self.view setBackgroundColor:[UIColor whiteColor]]; }
Itu dia! Sekarang Anda dapat menjalankan aplikasi dan melihat bagaimana tiga tugas yang berbeda dapat dilakukan pada saat yang bersamaan. Ingat bahwa ketika eksekusi objek NSOperation selesai, maka secara otomatis akan meninggalkan antrian.
Kesimpulan
Banyak dari Anda mungkin telah menemukan bahwa kode aktual untuk menjalankan aplikasi multi-tasking hanya membutuhkan beberapa baris kode. Tampaknya beban kerja terbesar adalah menerapkan metode yang diperlukan yang bekerja dengan setiap tugas. Namun demikian, metode ini adalah cara mudah untuk mengembangkan aplikasi multi-threading di iOS.
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weekly