August 31, 2011

สร้าง Object จากชื่อคลาส

เราสามารถสร้าง Object แบบกำหนดชื่อคลาสได้ดังนี้


id *object = [[NSClassFromString(@"MyClassName") alloc] init];

ประโยชน์ก็คือในบางกรณีเราไม่สามารถรู้ได้ตั้งแต่ตอนเขียนโปรแกรมว่าจังหวะนี้ควรจะโหลด Object ของคลาสไหน จนกว่าจะถึงตอนที่ต้องใช้จริงๆ

August 29, 2011

บังคับให้ UI Orientation เปลี่ยน

เราสามารถบังคับให้ User Interface Orientation ใน iOS Device เปลี่ยนได้
ยกตัวอย่างการ toggle ไปมาระหว่ง UI แนวตั้งกับแนวนอน สามารถทำได้ดังนี้

    if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){
        [[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
    }else{
        [[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait];
    }

August 24, 2011

Exception กับ @try, @catch และ @finally

ผมไม่ค่อยเห็นใครใช้การดักจับ Exception โดย try...catch บล็อคสักเท่าไหร่ในการเขียนโปรแกรมด้วยภาษา Objective-C เท่าที่เห็นจะเป็นการโยน NSError เข้าไป และอ้างถึงมันในภายหลัง หรือไม่ก็มี delegate message back กลับมาบอกว่ามันมีการทำงานผิดพลาดอย่างไร


ในภาษา Object-C การดักจับ Exception ให้ทำดังนี้


    // 1 สร้าง Array เปล่าๆ ขึ้นมาก่อน
    NSArray *array = [[NSArray alloc] init];
    
    @try {
        // 2 อ้างถึง element ใน Array ที่ไม่ได้มีอยู่จริง
        NSLog(@"object = %@", [array objectAtIndex: 0]);
        
    }@catch (NSException *exception) {
        // เมื่อเกิดข้อผิดพลาดขึ้นโค๊ดข้างในนี้จะถูกเรียกให้ทำงาน
        NSLog(@"Exception name = %@", exception.name);
        NSLog(@"Exception reason = %@", exception.reason);
        
    }@finally {
        // โค๊ดในบล็อคนี้จะถูกเรียกให้ทำงานเสมอ
        NSLog(@"finally");
        [array release];
    }


จากโค๊ด เป็นการยกตัวอย่างการเข้าถึง Element ใน Array ที่ไม่มีอยู่จริง โดยเริ่มจากสร้าง Array เปล่าๆ ขึ้นมาก่อน จากนั้นในจุดที่ 2 จะพยายามอ้างถึง Element ที่ 0 ของ Array ที่สร้างขึ้นมา ซึ่งไม่ได้มีอยู่จริง และทำให้เกิดข้อผิดพลาดเกิดขึ้น เมื่อใดก็ตามที่โค๊ดในบล็อค @try เกิดข้อผิดพลาดขึ้น มันจะหยุดทำงานทันทีและโค๊ดในบล็อค @catch จะเริ่มทำงานต่อ ส่วน @finally นั้นจะทำงานเสมอไม่ว่าจะเกิด Exception ขึ้นหรือไม่ก็ตาม


ส่วนผลลัพธ์ที่ได้จะเป็นดังนี้


Exception name = NSRangeException
Exception reason = *** -[NSArray objectAtIndex:]: index 0 beyond bounds for empty array
finally


การโยน Exception ออกจามาจาก function ที่เรียกใช้

- (void) testException{
    
    if(YES){
        // สร้าง Exception และโยนมันออกไปจากตรงนี้
        NSException *exception = [NSException exceptionWithName: @"Exception"
                                                         reason: @"There are someting wrong"
                                                       userInfo: nil];
        
        @throw exception;
    }
}


เมื่อมีการใช้งาน method - (void) testException  และเกิดข้อผิดพลาดขึ้น เราสามารถโยน Exception ออกจาก function ได้ตามโค๊ดด้านบน


ลองเอา function ที่จะมีการ throw exception ออกมามาใช้งานใน @try บล็อค


@try {
        
        [self testException];
        
    }@catch (NSException *exception) {
        NSLog(@"Exception name = %@", exception.name);
        NSLog(@"Exception reason = %@", exception.reason);
        
    }@finally {
        NSLog(@"finally");
        [array release];
    }


จากนั้นลองรันโปรแกรมดูใหม่ ผลจะออกมาดังนี้

Exception name = Exception
Exception reason = There are someting wrong
finally


:)