2011年8月28日 星期日

Objective-C 的記憶體回收機制(中)

在上一篇文章裡面談到了自己對物件記憶體的操作,難道就只有開發者會對物件做計數器(retainCount)的操作嗎?答案是否定!有一些 api 會自動對物件的 retainCount +1或是 -1,最常見的例子就是陣列的操作。例如:

NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity : 0];//array.retainCount = 1

NSString *str1 = [[NSString alloc] initWithString : @"A"];//str1.retainCount = 1
NSString *str2 = [[NSString alloc] initWithString : @"A"];//str2.retainCount = 1

[arr addObject : str1];//str1.retainCount = 2
[arr addObject : str2];//str2.retainCount = 2

[arr removeObject : str1];//str1.retainCount = 1
[arr release];//array.retainCount = 0;str2.retainCount = 1

//系統回收 array

[str1 release];//str1.retainCount = 0
[str2 release];//str2.retainCount = 0

//系統回收str1&str2

Objective-C 的記憶體回收機制(上)

這陣子為了 iPhone 學了 Objectiv-C ,一直對他的記憶體管理機制頗有微詞(笑),什麼時候該釋放,什麼時候該保留,真的是一點頭緒都沒有!建議初學者先把 Apple 官方的關於記憶體回收的說明文件先讀過一遍。(網頁版,PDF版),內容有空的話我再翻譯!

首先先解釋為什麼變數有時候要加星號(*),有時候又不加。這是因為在 C 與 C++,以及基於這兩種語言加以改良的 Objective-C ,星號(*)代表的意思是指向某個記憶體的指標(pointer), 而不加星號(*)表示是取值,例如:

int number = 0;//取值

char[] name = ['n','a','m','e'];
char *str = name;//取址

2011年8月23日 星期二

html 檔案上傳控制項 onChange事件只會觸發一次

困擾了好久的問題,終於解決了!

原本的事件繫結

$("#file_upload").bind('change',function(){});

改成

$("#file_upload").live('change',function(){});

----以上是 JQuery 的用法-------

一般的做法是替換掉file_upload

$('#file_upload').replaceWith('<input id="file_upload" name="file_upload" type="file">');

2011年7月28日 星期四

Android - MapView上面的圖片跟著縮放

昨天在ptt的AndroidDev板看到有鄉民在問怎麼讓MapView上面的圖片跟著縮放,想起之前也有做過類似的測試,就寫了這篇和大家分享。

首先先看到layout檔的排版:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <com.google.android.maps.MapView
  android:id="@+id/mView_Main"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:apiKey="你自己的key">
 </com.google.android.maps.MapView>
</LinearLayout>

很簡單的一個地圖畫面。

Objective-C 的 self

今天查被Apple reject的原因,剛好看到有關self的一些解釋,趕緊記下來免得忘記。

假設現在有個類別Test,裡面有一個NSData的成員。

@interface Test : NSObject {
    NSData *iData;
}

@property(nonatomic,retain) NSData *iData;

@end

當我們使用 self.NSData 的時候,就等同於呼叫編譯器幫我們自動產生的getter方法,retain + 1。
當我們使用 self.NSData = [[NSData alloc] init],就等同於呼叫setter的方法。

而編譯器產生的getter/setter就等同於自己寫的:

-(void) setIData : (NSData *) newData {
  if(iData != newData){
    [iData release];
    iData = [newData retain];
  }
}

-(NSData *) getIData {
  return iData;
}

另外,在dealloc時,就不要再用self了!