2010年10月25日 星期一

Objective-C : Allocate Object by String

假設我們現在有定義好的Segment.h, Segment.m Segment.xib,三個檔案存在bundle裡。其中Segment是UIViewController的子類別所以一般的情況下我們是這樣產生物件的
Segment * myViewCon = [[Segment alloc] initWithNibName:@"Segment" bundle:nil];

但在Objective-C下有一個很有趣的方法可以產生物件。利用NSClassFromString
寫法如下
-(id) createViewController:(NSString *) className{
    NSString* theClassName = className;
    Class theClass = NSClassFromString(theClassName);
    NSObject* viewController = [[theClass performSelector:@selector(alloc)] initWithNibName:className bundle:nil];
    [viewController autorelease];
    return viewController;
}

試試看,很好玩地~~~

2010年10月11日 星期一

iOS - UIImagePickerController 的怪情況在3GS上的測試

很簡單的一個View-Based的project一打開UIImagePickerController就會讓記憶體暴衝,然後還收到level=2 的警告,我想這件事大家多多少少有遇過(Apple大哥,調一下啊)

還有一個很怪的情況
先來看畫面
中間的藍綠色是一個UIImageView
左上方的按鈕是用來打開相機拍照
右上方的按鈕是用來測試直接把一張圖片轉成UIImage丟給中間的UIImageView

大家都知道,要抓下相機拍到的照片就要用
                       
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
   
   
    NSLog(@"finished ");
 
    UIImage * catched = [info    objectForKey:@"UIImagePickerControllerOriginalImage"];
    if (catched == nil) {
        NSLog(@"it is nil");
    }
    NSLog(@"%@", catched);
    myImageView.image = catched ;

   
    [[picker parentViewController] dismissModalViewControllerAnimated:YES];
    [picker release];
}

現在的uiimage都放在info裡面,要用 UIImagePickerControllerOriginalImage  這個key抓出來
之後丟到 myImageView 也就是中間的UIImageView
然後dissmiss picker, release picker
一切都很合理
問題就會出現 (3GS下測試的)
不管怎麼按,中間的UIImageView都不會更新 orz...
筆者找了一下,網路上有個叫Michael的朋友就說了,其實要改成這樣
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
   
    [[picker parentViewController] dismissModalViewControllerAnimated:YES];
    [picker release];
    NSLog(@"finished ");
 
    UIImage * catched = [info    objectForKey:@"UIImagePickerControllerOriginalImage"];
    if (catched == nil) {
        NSLog(@"it is nil");
    }
    NSLog(@"%@", catched);
    myImageView.image = catched ;
  

}


先把picker dismiss 又 release pcker後
再去把值放到myImageView
天啊,這是置死地於後生,敗中求勝的方法嗎?
本人對這個解法的作者的景仰有如滔滔江水,連綿不絕~~~
筆者附上程式碼
有空的朋友可以回家試試

程式碼