• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 319, comments - 22, trackbacks - 0, articles - 11
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            很多程序有這樣的功能,雙擊某個圖片可以打開源文件,右鍵菜單中的Show in Finder功能,Cocoa中對這塊支持較好,有現成的方法:

            [[NSWorkspace sharedWorkspace] openFile:fileName];

            [[NSWorkspace sharedWorkspace] selectFile:fileName inFileViewerRootedAtPath:path];  // 如果只打開目錄不需要選中具體文件,fileName可為nil。

            posted @ 2013-01-07 23:23 RTY 閱讀(651) | 評論 (0)編輯 收藏

            http://www.cnbeta.com/articles/219634.htm

            感謝GZX的投遞
            今天剛剛收到Windows 8商店的提示,掃雷可以更新了,于是興致勃勃的下載最新版的Windows 8掃雷,截圖給大家看。
            從開始屏幕上看,掃雷的應用磁帖并沒有發生太大的變化。


            但是打開應用之后,就會發現有了不一樣的地方。
            在主題部分,你將會看到新的主題“傳統主題”。

            當你點擊了傳統主題后,游戲選項卡部分將會變為傳統的掃雷樣式。

            隨意進入一個選項卡,就可以看到我們熟悉的界面

            進入自定義模式后,我們可以看到三個選項條,分別為:長、寬以及雷數,最大值如圖所示

            進入冒險模式后,我們可以發現與之前的版本并沒有太大變化

            出現了廣告界面則是在“每日挑戰”中

            打開“每日挑戰”,我們可以看到界面的右側多了一個廣告顯示的位置,如下圖紅框內所示

            而當你選擇了任意一個模式后,就被強迫觀看30s的廣告

            視頻緩沖階段,你會看到如下文字:“Thanks to our sponsors, this game is free(感謝我們的贊助商,本游戲完全免費)”

            而觀看視頻時,它還會提示你游戲開始的時間,注意中下部
            進入游戲后,則與之前介紹的界面完全類似


            這里要提示的是,每次打開掃雷應用的“每日挑戰”,你只需要觀看一次視頻廣告(每次的廣告均有所不同),就可以體驗全部的三個模式
             
            那么,你準備好升級你的掃雷了么?

            posted @ 2012-12-26 10:32 RTY 閱讀(404) | 評論 (0)編輯 收藏

            UITabBarController是選項卡欄導航控制器,顯示效果是在頁面底部有多個選項卡,通過點擊不同選項卡可以在不同的ViewController之間進行切換。


            這種對象的層次結構至少包含6個對象:

            一個UITabBarController;

            兩個UIViewController;

            一個UITabBar;

            兩個UITabBarItem;


            UITabBarController 是選項卡欄視圖控制器,UITabBar是底部兩個UITabBarItem的容器,管理兩個UITabBarItem,每個UITabBarItem對 應一個UIViewController,然后每個UIViewController都有自己的視圖和視圖控制器。


            UITabBarController中有一個viewControllers屬性,這是一個NSArray,包含選項卡控制器的視圖控制器


            下面來用代碼創建一個UITabBarController:

            下面是工程結構:

            首先創建兩個帶xib文件的ViewController,分別為FirstViewController和SecondViewController

            然后在AppDelegate.h中聲明@property (strong,nonatomic) UITabBarController *tabBarController;,并添加協議UITabBarControllerDelegate


            在.m中實現如下代碼:

            1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions  
            2. {  
            3.     self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];  
            4.     // Override point for customization after application launch.  
            5.      
            6.     //第一個tab的viewController  
            7.     FirstViewController *firstViewController = [[FirstViewController alloc]init];  
            8.      
            9.     //如果在這里指定tabitem標題,則在FirstViewController中指定self.tabBarItem.title則不生效     
            10.     firstViewController.title = @"First view";  
            11.      
            12.     UITabBarItem *firstItem = [[UITabBarItem alloc]initWithTitle:@"First" image:nil tag:1];  
            13.     [firstItem setFinishedSelectedImage:[UIImage imageNamed:@"p1"] withFinishedUnselectedImage:[UIImage imageNamed:@"p1_f"]];  
            14.     firstViewController.tabBarItem = firstItem;  
            15.      
            16.      
            17.     SecondViewController *secondViewController = [[SecondViewController alloc]init];  
            18.      
            19.     //構建TabBarItem  
            20.     UITabBarItem *secondItem = [[UITabBarItem alloc]initWithTitle:@"Second" image:nil tag:2];  
            21.      
            22.     //設置選中和非選中狀態下的圖片  
            23.     [secondItem setFinishedSelectedImage:[UIImage imageNamed:@"p2_f"] withFinishedUnselectedImage:[UIImage imageNamed:@"p2"]];  
            24.     //右上角小圖標  
            25.    [secondItem setBadgeValue:@"2"];  
            26.     //指定tabBarItem  
            27.     secondViewController.tabBarItem = secondItem;  
            28.     [secondItem release];  
            29.      
            30.     //構建UITabBarController并指定代理為本身  
            31.     self.tabBarController = [[[UITabBarController alloc]init] autorelease];  
            32.     self.tabBarController.delegate = self;  
            33.      
            34.     //為UITabBarController添加TabBarItem  
            35.     self.tabBarController.viewControllers = [NSArray arrayWithObjects:firstViewController,secondViewController, nil];  
            36.      
            37.     [firstViewController release];  
            38.     [secondViewController release];  
            39.      
            40.     //設置選中哪個tab  
            41. //    [self.tabBarController setSelectedIndex:0];  
            42.      
            43.     //指定根視圖  
            44.     self.window.rootViewController  = self.tabBarController;  
            45.      
            46.     self.window.backgroundColor = [UIColor whiteColor];  
            47.     [self.window makeKeyAndVisible];  
            48.     return YES;  
            49. }  




            posted @ 2012-12-26 10:31 RTY 閱讀(1176) | 評論 (0)編輯 收藏

              在這篇文章中,我想向大家介紹如何進行Lua程序設計。我假設大家都學過至少一門編程語言,比如Basic或C,特別是C。因為Lua的最大用途是在宿主程序中作為腳本使用的。

              Lua 的語法比較簡單,學習起來也比較省力,但功能卻并不弱。

              在Lua中,一切都是變量,除了關鍵字。請記住這句話。

            I. 首先是注釋

              寫一個程序,總是少不了注釋的。
              在Lua中,你可以使用單行注釋和多行注釋。
              單行注釋中,連續兩個減號"--"表示注釋的開始,一直延續到行末為止。相當于C++語言中的"http://"。
              多行注釋中,由"--[["表示注釋開始,并且一直延續到"]]"為止。這種注釋相當于C語言中的"/*…*/"。在注釋當中,"[["和"]]"是可以嵌套的。

            II. Lua編程

              經典的"Hello world"的程序總是被用來開始介紹一種語言。在Lua中,寫一個這樣的程序很簡單:
              print("Hello world")
              在Lua中,語句之間可以用分號";"隔開,也可以用空白隔開。一般來說,如果多個語句寫在同一行的話,建議總是用分號隔開。
              Lua 有好幾種程序控制語句,如:

              條件控制:if 條件 then … elseif 條件 then … else … end
              While循環:while 條件 do … end
              Repeat循環:repeat … until 條件
              For循環:for 變量 = 初值,終點值,步進 do … end
              For循環:for 變量1,變量2,… ,變量N in表或枚舉函數 do … end

              注意一下,for的循環變量總是只作用于for的局部變量,你也可以省略步進值,這時候,for循環會使用1作為步進值。
              你可以用break來中止一個循環。
              如果你有程序設計的基礎,比如你學過Basic,C之類的,你會覺得Lua也不難。但Lua有幾個地方是明顯不同于這些程序設計語言的,所以請特別注意。

              .語句塊
                語句塊在C++中是用"{"和"}"括起來的,在Lua中,它是用do 和 end 括起來的。比如: 
                do print("Hello") end
                你可以在 函數 中和 語句塊 中定局部變量。

              .賦值語句
                賦值語句在Lua被強化了。它可以同時給多個變量賦值。
                例如:
                a,b,c,d=1,2,3,4
                甚至是:
                a,b=b,a -- 多么方便的交換變量功能啊。
                在默認情況下,變量總是認為是全局的。假如你要定義局部變量,則在第一次賦值的時候,需要用local說明。比如:
                local a,b,c = 1,2,3 -- a,b,c都是局部變量

              .數值運算
                和C語言一樣,支持 +, -, *, /。但Lua還多了一個"^"。這表示指數乘方運算。比如2^3 結果為8, 2^4結果為16。
                連接兩個字符串,可以用".."運處符。如:
                "This a " .. "string." -- 等于 "this a string"

              .比較運算
                < > <= >= == ~=
                分別表示 小于,大于,不大于,不小于,相等,不相等
                所有這些操作符總是返回true或false。
                對于Table,Function和Userdata類型的數據,只有 == 和 ~=可以用。相等表示兩個變量引用的是同一個數據。比如:
                a={1,2}
                b=a
                print(a==b, a~=b) -- true, false
                a={1,2}
                b={1,2}
                print(a==b, a~=b) -- false, true

              .邏輯運算
                and, or, not
                其中,and 和 or 與C語言區別特別大。
                在這里,請先記住,在Lua中,只有false和nil才計算為false,其它任何數據都計算為true,0也是true!
                and 和 or的運算結果不是true和false,而是和它的兩個操作數相關。
                a and b:如果a為false,則返回a;否則返回b
                a or b:如果 a 為true,則返回a;否則返回b

                舉幾個例子:
                 print(4 and 5) --> 5
                 print(nil and 13) --> nil
                 print(false and 13) --> false
                 print(4 or 5) --> 4
                 print(false or 5) --> 5

                在Lua中這是很有用的特性,也是比較令人混洧的特性。
                我們可以模擬C語言中的語句:x = a? b : c,在Lua中,可以寫成:x = a and b or c。
                最有用的語句是: x = x or v,它相當于:if not x then x = v end 。

              .運算符優先級,從高到低順序如下:
                ^
                not - (一元運算)
                 * /
                 + -
                 ..(字符串連接)
                 < > <= >= ~= ==
                 and
                 or

            ==========================================================

             

            III. 關鍵字

              關鍵字是不能做為變量的。Lua的關鍵字不多,就以下幾個:
              and break do else elseif
              end false for function if
              in local nil not or
              repeat return then true until while

            IV. 變量類型

              怎么確定一個變量是什么類型的呢?大家可以用type()函數來檢查。Lua支持的類型有以下幾種:

              Nil 空值,所有沒有使用過的變量,都是nil。nil既是值,又是類型。
              Boolean 布爾值
              Number 數值,在Lua里,數值相當于C語言的double
              String 字符串,如果你愿意的話,字符串是可以包含'\0'字符的
              Table 關系表類型,這個類型功能比較強大,我們在后面慢慢說。
              Function 函數類型,不要懷疑,函數也是一種類型,也就是說,所有的函數,它本身就是一個變量。
              Userdata 嗯,這個類型專門用來和Lua的宿主打交道的。宿主通常是用C和C++來編寫的,在這種情況下,Userdata可以是宿主的任意數據類型,常用的有Struct和指針。
              Thread   線程類型,在Lua中沒有真正的線程。Lua中可以將一個函數分成幾部份運行。如果感興趣的話,可以去看看Lua的文檔。

            V. 變量的定義

              所有的語言,都要用到變量。在Lua中,不管你在什么地方使用變量,都不需要聲明,并且所有的這些變量總是全局變量,除非,你在前面加上"local"。
              這一點要特別注意,因為你可能想在函數里使用局部變量,卻忘了用local來說明。
              至于變量名字,它是大小寫相關的。也就是說,A和a是兩個不同的變量。
              定義一個變量的方法就是賦值。"="操作就是用來賦值的
              我們一起來定義幾種常用類型的變量吧。
              A. Nil
                正如前面所說的,沒有使用過的變量的值,都是Nil。有時候我們也需要將一個變量清除,這時候,我們可以直接給變量賦以nil值。如:
                var1=nil -- 請注意 nil 一定要小寫

              B. Boolean
                布爾值通常是用在進行條件判斷的時候。布爾值有兩種:true 和 false。在Lua中,只有false和nil才被計算為false,而所有任何其它類型的值,都是true。比如0,空串等等,都是true。不要被C語言的習慣所誤導,0在Lua中的的確確是true。你也可以直接給一個變量賦以Boolean類型的值,如:
                varboolean = true

              C. Number
                在Lua中,是沒有整數類型的,也不需要。一般情況下,只要數值不是很大(比如不超過100,000,000,000,000),是不會產生舍入誤差的。在很多CPU上,實數的運算并不比整數慢。
                實數的表示方法,同C語言類似,如:
                4 0.4 4.57e-3 0.3e12 5e+20

              D. String
                字符串,總是一種非常常用的高級類型。在Lua中,你可以非常方便的定義很長很長的字符串。
                字符串在Lua中有幾種方法來表示,最通用的方法,是用雙引號或單引號來括起一個字符串的,如:
                "This is a string."
                和C語言相同的,它支持一些轉義字符,列表如下:
                \a bell
                \b back space
                \f form feed
                \n newline
                \r carriage return
                \t horizontal tab
                \v vertical tab
                \\ backslash
                \" double quote
                \' single quote
                \[ left square bracket
                \] right square bracket

                由于這種字符串只能寫在一行中,因此,不可避免的要用到轉義字符。加入了轉義字符的串,看起來實在是不敢恭維,比如:
                "one line\nnext line\n\"in quotes\", 'in quotes'"
                一大堆的"\"符號讓人看起來很倒胃口。如果你與我有同感,那么,我們在Lua中,可以用另一種表示方法:用"[["和"]]"將多行的字符串括起來,如:
                page = [[
                <HTML>
                  <HEAD>
                    <TITLE>An HTML Page</TITLE>
                  </HEAD>
                  <BODY>
                    <A HREF="http://www.lua.org">Lua</A>
                    [[a text between double brackets]]
                  </BODY>
                </HTML>
                ]]

                值得注意的是,在這種字符串中,如果含有單獨使用的"[["或"]]"就仍然得用"\["或"\]"來避免歧義。當然,這種情況是極少會發生的。



            ==================================================================

            E. Table
                關系表類型,這是一個很強大的類型。我們可以把這個類型看作是一個數組。只是C語言的數組,只能用正整數來作索引;在Lua中,你可以用任意類型來作數組的索引,除了nil。同樣,在C語言中,數組的內容只允許一種類型;在Lua中,你也可以用任意類型的值來作數組的內容,除了nil。
                Table的定義很簡單,它的主要特征是用"{"和"}"來括起一系列數據元素的。比如:

                T1 = {} -- 定義一個空表
                T1[1]=10 -- 然后我們就可以象C語言一樣來使用它了。
                T1["John"]={Age=27, Gender="Male"}
                這一句相當于:
                T1["John"]={} -- 必須先定義成一個表,還記得未定義的變量是nil類型嗎
                T1["John"]["Age"]=27
                T1["John"]["Gender"]="Male"
                當表的索引是字符串的時候,我們可以簡寫成:
                T1.John={}
                T1.John.Age=27
                T1.John.Gender="Male"
                或
                T1.John{Age=27, Gender="Male"}
                這是一個很強的特性。

                在定義表的時候,我們可以把所有的數據內容一起寫在"{"和"}"之間,這樣子是非常方便,而且很好看。比如,前面的T1的定義,我們可以這么寫:

                T1=
                {
                  10, -- 相當于 [1] = 10
                  [100] = 40,
                  John= -- 如果你原意,你還可以寫成:["John"] =
                  {
                    Age=27, -- 如果你原意,你還可以寫成:["Age"] =27
                    Gender=Male -- 如果你原意,你還可以寫成:["Gender"] =Male
                  },
                  20 -- 相當于 [2] = 20
                }

                看起來很漂亮,不是嗎?我們在寫的時候,需要注意三點:
                第一,所有元素之間,總是用逗號","隔開;
                第二,所有索引值都需要用"["和"]"括起來;如果是字符串,還可以去掉引號和中括號;
                第三,如果不寫索引,則索引就會被認為是數字,并按順序自動從1往后編;

                表類型的構造是如此的方便,以致于常常被人用來代替配置文件。是的,不用懷疑,它比ini文件要漂亮,并且強大的多。

              F. Function
                函數,在Lua中,函數的定義也很簡單。典型的定義如下:
                function add(a,b) -- add 是函數名字,a和b是參數名字
                 return a+b -- return 用來返回函數的運行結果
                end

                請注意,return語言一定要寫在end之前。假如你非要在中間放上一句return,那么請寫成:do return end。
                還記得前面說過,函數也是變量類型嗎?上面的函數定義,其實相當于:
                add = function (a,b) return a+b end
                當你重新給add賦值時,它就不再表示這個函數了。你甚至可以賦給add任意數據,包括nil (這樣,你就清除了add變量)。Function是不是很象C語言的函數指針呢?

                和C語言一樣,Lua的函數可以接受可變參數個數,它同樣是用"…"來定義的,比如:
                function sum (a,b,…)
                如果想取得…所代表的參數,可以在函數中訪問arg局部變量(表類型)得到。
                如 sum(1,2,3,4)
                則,在函數中,a = 1, b = 2, arg = {3, 4}
                更可貴的是,它可以同時返回多個結果,比如:
                function s()
                  return 1,2,3,4
                end
                a,b,c,d = s() -- 此時,a = 1, b = 2, c = 3, d = 4
            前面說過,表類型可以擁有任意類型的值,包括函數!因此,有一個很強大的特性是,擁有函數的表,哦,我想更恰當的應該說是對象吧。Lua可以使用面向對象編程了。不信?那我舉例如下:

                t =
                {
                 Age = 27
                 add = function(self, n) self.Age = self.Age+n end
                }
                print(t.Age) -- 27
                t.add(t, 10)
                print(t.Age) -- 37

                不過,t.add(t,10) 這一句實在是有點土對吧?沒關系,在Lua中,你可以簡寫成:
                t:add(10) -- 相當于 t.add(t,10)

              G. Userdata 和 Thread
                這兩個類型的話題,超出了本文的內容,就不打算細說了。

            ===========================================================

            VI. 結束語

              就這么結束了嗎?當然不是,接下來,需要用Lua解釋器,來幫助你理解和實踐了。這篇小文只是幫助你大體了解Lua的語法。如果你有編程基礎,相信會很快對Lua上手了。
              就象C語言一樣,Lua提供了相當多的標準函數來增強語言的功能。使用這些標準函數,你可以很方便的操作各種數據類型,并處理輸入輸出。有關這方面的信息,你可以參考《Programming in Lua 》一書,你可以在網絡上直接觀看電子版,網址為:http://www.lua.org/pil/index.html
              當然,Lua的最強大的功能是能與宿主程序親蜜無間的合作,因此,下一篇文章,我會告訴大家,如何在你的程序中使用Lua語言作為腳本,使你的程序和Lua腳本進行交互。

            使用流程

            1. 函數的使用

                以下程序演示了如何在Lua中使用函數, 及局部變量
            例e02.lua
            -- functions 
            function pythagorean(a, b) 
            local c2 = a^2 + b^2 
            return sqrt(c2) 
            end 
            print(pythagorean(3,4))

            運行結果
            5

            程序說明
            在Lua中函數的定義格式為:
            function 函數名(參數)
            ...
            end
                與Pascal語言不同, end不需要與begin配對, 只需要在函數結束后打個end就可以了.本例函數的作用是已知直角三角形直角邊, 求斜邊長度. 參數a,b分別表示直角邊長,
                在函數內定義了local形變量用于存儲斜邊的平方. 與C語言相同, 定義在函數內的代碼不會被直接執行, 只有主程序調用時才會被執行.
                local表示定義一個局部變量, 如果不加local剛表示c2為一個全局變量, local的作用域是在最里層的end和其配對的關鍵字之間, 如if ... end, while ... end等。全局變量的作用域是整個程序。

            2. 循環語句

            例e03.lua
            -- Loops 
            for i=1,5 do 
            print("i is now " .. i) 
            end

            運行結果
            i is now 1 
            i is now 2 
            i is now 3 
            i is now 4 
            i is now 5

            程序說明
                這里偶們用到了for語句
            for 變量 = 參數1, 參數2, 參數3 do
            循環體
            end
                變量將以參數3為步長, 由參數1變化到參數2
            例如: 
            for i=1,f(x) do print(i) end
            for i=10,1,-1 do print(i) end

                這里print("i is now " .. i)中,偶們用到了..,這是用來連接兩個字符串的,偶在(1)的試試看中提到的,不知道你們答對了沒有。雖然這里i是一個整型量,Lua在處理的時候會自動轉成字符串型,不需偶們費心。

            3. 條件分支語句

            例e04.lua
            -- Loops and conditionals 
            for i=1,5 do
            print(“i is now “ .. i)
            if i < 2 then 
            print(“small”) 
            elseif i < 4 then 
            print(“medium”) 
            else 
            print(“big”) 
            end 
            end

            運行結果
            i is now 1 
            small 
            i is now 2 
            medium 
            i is now 3 
            medium 
            i is now 4 
            big 
            i is now 5 
            big

            程序說明
                if else用法比較簡單, 類似于C語言, 不過此處需要注意的是整個if只需要一個end,哪怕用了多個elseif, 也是一個end.
            例如
            if op == "+" then
            r = a + b
            elseif op == "-" then
            r = a - b
            elseif op == "*" then
            r = a*b
            elseif op == "/" then
            r = a/b
            else
            error("invalid operation")
            end


            4.試試看

                Lua中除了for循環以外, 還支持多種循環, 請用while...do和repeat...until改寫本文中的for程序。

            數組的使用

            1.簡介

                Lua語言只有一種基本數據結構, 那就是table, 所有其他數據結構如數組啦,類啦, 都可以由table實現.

            2.table的下標

            例e05.lua
            -- Arrays 
            myData = {} 
            myData[0] = “foo” 
            myData[1] = 42

            -- Hash tables 
            myData[“bar”] = “baz”

            -- Iterate through the 
            -- structure 
            for key, value in myData do 
            print(key .. “=“ .. value) 
            end

            輸出結果
            0=foo 
            1=42 
            bar=baz

            程序說明
                首先定義了一個table myData={}, 然后用數字作為下標賦了兩個值給它. 這種定義方法類似于C中的數組, 但與數組不同的是, 每個數組元素不需要為相同類型,就像本例中一個為整型, 一個為字符串.

                程序第二部分, 以字符串做為下標, 又向table內增加了一個元素. 這種table非常像STL里面的map. table下標可以為Lua所支持的任意基本類型, 除了nil值以外.

                Lua對Table占用內存的處理是自動的, 如下面這段代碼
            a = {}
            a["x"] = 10
            b = a -- `b' refers to the same table as `a'
            print(b["x"]) --> 10
            b["x"] = 20
            print(a["x"]) --> 20
            a = nil -- now only `b' still refers to the table
            b = nil -- now there are no references left to the table
                b和a都指向相同的table, 只占用一塊內存, 當執行到a = nil時, b仍然指向table,
                而當執行到b=nil時, 因為沒有指向table的變量了, 所以Lua會自動釋放table所占內存

            3.Table的嵌套

                Table的使用還可以嵌套,如下例
            例e06.lua
            -- Table ‘constructor’ 
            myPolygon = { 
            color=“blue”, 
            thickness=2, 
            npoints=4; 
            {x=0, y=0}, 
            {x=-10, y=0}, 
            {x=-5, y=4}, 
            {x=0, y=4} 
            }

            -- Print the color 
            print(myPolygon[“color”])

            -- Print it again using dot 
            -- notation 
            print(myPolygon.color)

            -- The points are accessible 
            -- in myPolygon[1] to myPolygon[4]

            -- Print the second point’s x 
            -- coordinate 
            print(myPolygon[2].x)

            程序說明

                首先建立一個table, 與上一例不同的是,在table的constructor里面有{x=0,y=0}, 這是什么意思呢? 這其實就是一個小table, 定義在了大table之內, 小table的table名省略了.最后一行myPolygon[2].x,就是大table里面小table的訪問方式.

            posted @ 2012-11-29 16:32 RTY 閱讀(386) | 評論 (0)編輯 收藏

            xcode4的環境變量,Build Settings參數,workspace及聯編設置

            一、xcode4中的環境變量

            $(BUILT_PRODUCTS_DIR)

            build成功后的,最終產品路徑--可以在Build Settings參數的Per-configuration Build Products Path項里設置

            $(TARGET_NAME)

            目標工程名稱

            $(SRCROOT)

            工程文件(比如Nuno.xcodeproj)的路徑 

            $(CURRENT_PROJECT_VERSION)

            當前工程版本號

             

            其他:

            當編譯靜態庫,設備選模擬器(iPhone 5.0 Simulator),未設置任何Build Settings參數時,默認的基礎路徑:

            /Users/xxx/Library/Developer/Xcode/DerivedData/xxxWorkspace-caepeadwrerdcrftijaolkkagbjf

            下面用$()代替上面一長串東東

            $(SYMROOT) = $()/Build/Products

            $(BUILD_DIR) = $()/Build/Products

            $(BUILD_ROOT) =  $()/Build/Products

            這三個變量中的$()不會隨著Build Settings參數的設置而改變

            相反,以下可以通過設置而改變

            $(CONFIGURATION_BUILD_DIR) = $()/Build/Products/Debug-iphonesimulator

            $(BUILT_PRODUCTS_DIR) = $()/Build/Products/Debug-iphonesimulator

            $(CONFIGURATION_TEMP_DIR) = $()/Build/Intermediates/UtilLib.build/Debug-iphonesimulator

            $(TARGET_BUILD_DIR) = $()/Build/Products/Debug-iphonesimulator

            $(SDK_NAME) = iphonesimulator5.0

            $(PLATFORM_NAME) = iphonesimulator

            $(CONFIGURATION) = Debug

            $(TARGET_NAME) = UtilLib

            $(EXECUTABLE_NAME) = libUtilLib.a 可執行文件名

            ${IPHONEOS_DEPLOYMENT_TARGET} 5.0

            $(ACTION) = build

            $(CURRENTCONFIG_SIMULATOR_DIR) 當前模擬器路徑 

            $(CURRENTCONFIG_DEVICE_DIR) 當前設備路徑 

             

            $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME =

            $()/Build/Products/Debug-iphonesimulator

            $(PROJECT_TEMP_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) = $()/Build/Intermediates/UtilLib.build/Debug-iphonesimulator

             

            自定義變量

            ${CONFIGURATION}-iphoneos 表示:Debug-iphoneos

            ${CONFIGURATION}-iphonesimulator 表示:Debug-iphonesimulator

            $(CURRENTCONFIG_DEVICE_DIR) = ${SYMROOT}/${CONFIGURATION}-iphoneos

            $(CURRENTCONFIG_SIMULATOR_DIR) = ${SYMROOT}/${CONFIGURATION}-iphonesimulator

            自定義一個設備無關的路徑(用來存放各種架構arm6/arm7/i386輸出的產品)

            $(CREATING_UNIVERSAL_DIR) = ${SYMROOT}/${CONFIGURATION}-universal

            自定義變量代表的值

            $(CURRENTCONFIG_DEVICE_DIR) = $()/Build/Products/Debug-iphoneos

            $(CURRENTCONFIG_SIMULATOR_DIR) = $()/Build/Products/Debug-iphonesimulator

            $(CREATING_UNIVERSAL_DIR) = $()/Build/Products/Debug-universal

             

            iphoneos5.0下的編譯腳本:

            xcodebuild -project "UtilLib.xcodeproj" -configuration "Debug" -target "UtilLib" -sdk "iphoneos5.0" -arch "armv6 armv7" build RUN_CLANG_STATIC_ANALYZER=NO  $(BUILD_DIR)="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"

             

            iphonesimulator5.0下的編譯腳本:

            xcodebuild -project "UtilLib.xcodeproj" -configuration "Debug" -target "UtilLib" -sdk "iphonesimulator5.0" -arch "i386" build RUN_CLANG_STATIC_ANALYZER=NO $(BUILD_DIR)="${BUILD_DIR}"  BUILD_ROOT="${BUILD_ROOT}"

            加上下面一句表示輸出到文件:

            > "${BUILD_ROOT}.build_output"

             

            lipo腳本工具:合并iPhone模擬器和真機的靜態類庫,生成通用庫

            lipo -create -output "${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME}" "${CURRENTCONFIG_DEVICE_DIR}/${EXECUTABLE_NAME}"         "${CURRENTCONFIG_SIMULATOR_DIR}/${EXECUTABLE_NAME}"

            意思是:把"${CURRENTCONFIG_DEVICE_DIR}目錄下的.a文件,和${CURRENTCONFIG_SIMULATOR_DIR}目錄下的.a文件合并,

            在${CREATING_UNIVERSAL_DIR}目錄下,生成兩個設備都通用的靜態庫,

            例如:lipo -create -output xy.a x.a y.a

             

            二、xcode4中build Settings常見參數解析

            1.Installation Directory:安裝路徑

            靜態庫編譯時,在Build Settings中Installation Directory設置“$(BUILT_PRODUCTS_DIR)”

            Skip Install設為YES

            Installation Directory默認為/usr/local/lib

            因為Build Location默認時,.a文件會放在很長(比如:/Users/xxx/Library/Developer/Xcode/DerivedData/xxxProgram

            dalrvzehhtesxdfqhxixzafvddwe/Build/Products/Debug-iPhoneos)的路徑下,或是我們target指定的路徑

            Skip Install如果是NO,可能會被安裝到默認路徑/usr/local/lib

            2.Public Headers Folder Path:對外公開頭文件路徑

            設為“include”(具體的頭文件路徑為:$(BUILT_PRODUCTS_DIR)/include/xx.h)

            在最終文件.a同級目錄下生成一個include目錄

            默認:/usr/local/include

            Public Headers Folder Path這個路徑就是使用這lib的某工程需要依賴的外部頭文件.導入這路徑后,#include/import "xx.h"才能看到

            3.User Header Search Paths:依賴的外部頭文件搜索路徑

            設置為“$(BUILT_PRODUCTS_DIR)/include”

            和2中路徑對應

            4.Per-configuration Build Products Path:最終文件路徑

            比如設為“../app”,就會在工程文件.xcodeproj上一層目錄下的app目錄里,創建最終文件

            默認為$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 

            等于$(BUILT_PRODUCTS_DIR)

            5.Per-configuration Intermediate Build Files Path:臨時中間文件路徑

            默認為:$(PROJECT_TEMP_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)

            6.Code Signing Identity:真機調試的證書選擇

            選一個和Bundle identifier相對應的證書

            Library Search Paths:庫搜索路徑

            Architectures:架構,設為 armv6 或 armv7

            Valid Architectures:應用框架,可以設為 armv6、 armv7 或i386

            Product Name:工程文件名,默認為$(TARGET_NAME)

            Info.plist File:info文件路徑

            Build Variants:默認為normal

            Other Linker Flags:其他鏈接標簽

            設為“-ObjC”

            當導入的靜態庫使用了類別,需要設為-ObjC

            iOS Deployment Target:ios部署對象

            比如可以選擇設為,ios3到ios5的一種版本

            Prefix Header:預編頭文件(比如:UtilLib/UtilLib-Prefix.pch)

            Precompile Prefix Header:設為“Yes”,表示允許加入預編譯頭

             

            三、workspace(工作區)

            作用:管理多個工程(project),多工程聯編

             

            四、workspace多工程聯編設置

            一、

            1.新建一個靜態庫工程,比如UtilLib,并生成UtilLib.h和UtilLib.m文件

            2.選中需要公開的頭文件,

            把右側欄的Target Membership中設置為public

            或則,選中工程目錄target的Build Phases標簽的copy headers項,在public中添加要公開的頭文件

            3.Architectures設為:armv6 armv7

            4.Valid Architectures設為:armv6 armv7 i386

            5.Build Products Path設為:$(SRCROOT)/../build

            6.Per-configuration Build Products Path設為:

            $(SRCROOT)/../build/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)

            7.Per-configuration Intermediate Build Files Path設為:

            $(SRCROOT)/../build/$(TARGET_NAME).build/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)

            8.設置安裝路徑:Installation Directory項

            9.設置對外公開的頭文件路徑:Public Headers Folder Path項


            10.為靜態庫添加依賴的shell腳本

            選中工程目錄target的Build Phases標簽,點擊由下角的Add Build Phase按鈕

            在彈出的菜單里選擇Add run script項,然后頁面中會多出一個Run Script項

            在黑框里填寫"$SRCROOT/mergeArmSymbols.sh"

            建立對此腳本的依賴(編譯靜態庫的后會運行此腳本)

            如果編譯時設備選的是iphone simulator:

            則此腳本會在對應iphone device的產品目錄Debug-iphoneos中,生成對device有用的.a靜態庫,

            相反,如果設備選的是iphone device:

            則此腳本會在對應iphone simulator的產品目錄Debug-iphoneos中,生成對simulator有用的.a靜態庫

            最后,此腳本調用lipo工具,把本工程生成靜態庫與此腳本生成的靜態庫合并,生成simulator和device都通用的.a文件

             

            11.具體bash shell腳本如下

            mergeArmSymbols.sh

            下載右邊的圖片,然后把后綴改為.sh(其實就是上面的腳本,因為博客園只能上傳圖片)

            靜態庫編譯后的目錄結構如下:

             

            二、 

            1.新建主工程,比如Nuno,添加對靜態庫的依賴

            點擊工程,在Build Phases標簽的Link Binary With Libraries項中點擊加號添加UtilLib.a庫

            選中上面的紅色項,在右邊欄的Location選Relative to Project,把值設為../libs/libUtilLib.a

            2.設置主工程依賴的外部頭文件路徑:User Header Search Paths項

            $(SRCROOT)/../include

            3.設置Header Search Paths為:$(SRCROOT)/../include

            4.設置Library Search Paths為:$(SRCROOT)/../libs

            編譯運行即可實現聯編 

             

            (備注:選擇模擬器iphone 5.0 simulator,編譯靜態庫的時,最終文件會在Debug-iphonesimulator,就算成功.a文件還是紅色,

            這是可能是xcode的bug,不會自動切換路徑

            因為$(BUILT_PRODUCTS_DIR)所指的位置,是build/Debug-iphonesos,不是包含最終.a文件的Debug-iphonesimulator;

            選擇ios Device,編譯成的最終文件才在build/Debug-iphonesos下,.a文件變成非紅色

            所有得用mergeArmSymbols.sh腳本來解決)


            posted @ 2012-11-28 16:51 RTY 閱讀(671) | 評論 (0)編輯 收藏

            1.    // TODO —— 表示尚未完成的待辦事項。
            2.    // XXX —— 表示被注釋的代碼雖然實現了功能,但是實現方案有待商榷,希望將來能改進。
            3.    // FIXME —— 表示被注釋的代碼需要被修正。

            posted @ 2012-11-28 12:21 RTY 閱讀(432) | 評論 (0)編輯 收藏

            UIBarButtonSystemItem的樣式圖片

             

            typedef enum {
                UIBarButtonSystemItemDone,
                UIBarButtonSystemItemCancel,
                UIBarButtonSystemItemEdit,  
                UIBarButtonSystemItemSave,  
                UIBarButtonSystemItemAdd,
                UIBarButtonSystemItemFlexibleSpace,
                UIBarButtonSystemItemFixedSpace,
                UIBarButtonSystemItemCompose,
                UIBarButtonSystemItemReply,
                UIBarButtonSystemItemAction,
                UIBarButtonSystemItemOrganize,
                UIBarButtonSystemItemBookmarks,
                UIBarButtonSystemItemSearch,
                UIBarButtonSystemItemRefresh,
                UIBarButtonSystemItemStop,
                UIBarButtonSystemItemCamera,
                UIBarButtonSystemItemTrash,
                UIBarButtonSystemItemPlay,
                UIBarButtonSystemItemPause,
                UIBarButtonSystemItemRewind,
                UIBarButtonSystemItemFastForward,
            #if __IPHONE_3_0 <= __IPHONE_OS_VERSION_MAX_ALLOWED
                UIBarButtonSystemItemUndo,
                UIBarButtonSystemItemRedo,
            #endif
            #if __IPHONE_4_0 <= __IPHONE_OS_VERSION_MAX_ALLOWED
                UIBarButtonSystemItemPageCurl,
            #endif
            } UIBarButtonSystemItem;
            

             

             

            圖片如下:

            UIBarButtonSystemItemAdd

            UIBarButtonSystemItemCompose

            UIBarButtonSystemItemReply

            UIBarButtonSystemItemAction

            UIBarButtonSystemItemOrganize

            UIBarButtonSystemItemBookmarks

            UIBarButtonSystemItemSearch

            UIBarButtonSystemItemRefresh

            UIBarButtonSystemItemStop

            UIBarButtonSystemItemCamera

            UIBarButtonSystemItemTrash

            UIBarButtonSystemItemPlay

            UIBarButtonSystemItemPause

            UIBarButtonSystemItemRewind

            UIBarButtonSystemItemFastForward

            UIBarButtonSystemItemUndo

            UIBarButtonSystemItemRedo

            天下風云出我輩, 一入江湖歲月催. 皇圖霸業笑談中, 不勝人生一場醉.

            posted @ 2012-11-26 14:16 RTY 閱讀(3602) | 評論 (0)編輯 收藏

            原文:http://blog.csdn.net/weiqubo/article/details/8152326

            由init、loadView、viewDidLoad、viewDidUnload、dealloc的關系說起

            分類: iOS 273人閱讀 評論(0) 收藏 舉報

            對于iphone開發人員來說,內存管理是極為重要的技巧,哪怕程序的功能再強大,設計再漂亮,如果內存控制不好,也難逃程序莫名退出的噩運,這與網頁開發是完全不同的。

            內存控制里面有很多門道,在這里分析一下 viewDidUnload 和 dealloc 的區別,關于這兩者的區別的文章很多,但是大都是摘抄和翻譯官方文檔,有的也只是簡單的說兩句,并沒有詳細說出兩者具體的區別。

            在了解兩者之間的區別,首先要知道 view 的生命周期,google 里面有很多文章,可以先去搜一下,這里就不詳解了。

            顧名思義  viewDidUnload 就是當 view 被卸載以后執行的語句,它與 viewDidLoad 是相互呼應的。大家都知道官方的解釋是執行類似

             

            self.myOutlet = nil;

             

            的命令,但是為什么這么干,什么時候調用這個方法呢?

            這個方法是不能手動調用的,它實際上是當應用程序接收到手機內存警告的時候自動調用的方法,目的就是清空內存除當前 viewController 以外所有已經加載過的 viewController 里面的暫時不再使用的一些控件或數據,以避免應用程序應消耗內存過多被強制關閉。記住,是除當前正在展示的 view 所屬 viewController 以外所有已經在內存里面的 viewController 執行 viewDidUnload 方法, 而不是當前 viewController 執行 viewDidUnload,當然,這些 viewController 不會被 dealloc。所以在 viewDidUnload 里面一般都是釋放 IBOutlet 變量和在 viewDidLoad、viewWillAppear、viewDidAppear 等方法能夠重建的數據。而由其他頁面傳遞過來的數據或者無法經過 viewDidLoad、viewWillAppear、viewDidAppear 等方法重建的數據則不能釋放,舉例子說如果在 navigationController 由上一個頁面傳遞過來的一張圖片,在 viewDidUnload 里被釋放的話,則當 view 再次加載的時候就無法恢復了。

            那為什么要寫成 self.myOutlet = nil; ,實際上這個語法是執行了 property 里的setter 方法,而不是一個簡單的變量賦值,它干了兩件事:1、老數據 release 掉,2、新數據(nil)retain(當 property 設置為 retain 的情況下),當然對 nil retain 是無意義的。如果寫成 myOutlet = nil,那就是簡單的把 myOutlet 指向 nil,這樣內存就泄漏了,因為老數據沒有 release。而如果僅僅寫成 [myOutlet release] 也會有問題,因為當 view 被 dealloc 的時候會 再次 release,程序就出錯了,而對 nil release 是沒有問題的。
             
            dealloc 是當前 viewController 被釋放的時候,清空所有當前 viewController 里面的實體和數據來釋放內存,該方法也是自動調用的,無需手動執行。舉例說明當 modalView 被 dismissModalViewControllerAnimated 或者 navigationController 回到上一頁的時候,這個方法就會被自動調用。因為這個頁面已經不再使用了,所以可以把所有實體和數據都釋放(release)掉。

            其實兩者最大的區別就是: viewDidUnload 是內存除當前以外所有 viewController 同時執行,而 dealloc 只是當前 viewController 執行。這個是網上的材料沒有說明的。

            個人拙見,不對之處還請提正!

            PS: 很多朋友都說無法調試 viewDidUnload,其實是可以的。方法是在 iOS 模擬器的菜單里選 硬件->模擬內存警告,這個時候就可以看到 viewDidUnload 里面 NSLog 的東西了,可以試試在打開過的 viewController 里都 NSLog 一下看看效果。而 dealloc 里面可以直接 NSLog。



            由init、loadView、viewDidLoad、viewDidUnload、dealloc的關系說起

            init方法

            在init方法中實例化必要的對象(遵從LazyLoad思想)

            init方法中初始化ViewController本身

             loadView方法

            當view需要被展示而它卻是nil時,viewController會調用該方法。不要直接調用該方法。

            如果手工維護views,必須重載重寫該方法

            如果使用IB維護views,必須不能重載重寫該方法

            loadView和IB構建view

            你在控制器中實現了loadView方法,那么你可能會在應用運行的某個時候被內存管理控制調用。 如果設備內存不足的時候, view 控制器會收到didReceiveMemoryWarning的消息。 默認的實現是檢查當前控制器的view是否在使用。 如果它的view不在當前正在使用的view hierarchy里面,且你的控制器實現了loadView方法,那么這個view將被release, loadView方法將被再次調用來創建一個新的view。

             

            viewDidLoad方法

            viewDidLoad 此方法只有當view從nib文件初始化的時候才被調用。

            重載重寫該方法以進一步定制view

            在iPhone OS 3.0及之后的版本中,還應該重載重寫viewDidUnload來釋放對view的任何索引

            viewDidLoad后調用數據Model

            viewDidUnload方法

            當系統內存吃緊的時候會調用該方法(注:viewController沒有被dealloc)

            內存吃緊時,在iPhone OS 3.0之前didReceiveMemoryWarning是釋放無用內存的唯一方式,但是OS 3.0及以后viewDidUnload方法是更好的方式

            在該方法中將所有IBOutlet(無論是property還是實例變量)置為nil(系統release view時已經將其release掉了)

            在該方法中釋放其他與view有關的對象、其他在運行時創建(但非系統必須)的對象、在viewDidLoad中被創建的對象、緩存數據等 release對象后,將對象置為nil(IBOutlet只需要將其置為nil,系統release view時已經將其release掉了)

            一般認為viewDidUnload是viewDidLoad的鏡像,因為當view被重新請求時,viewDidLoad還會重新被執行

            viewDidUnload中被release的對象必須是很容易被重新創建的對象(比如在viewDidLoad或其他方法中創建的對象),不要release用戶數據或其他很難被重新創建的對象

            dealloc方法

            viewDidUnload和dealloc方法沒有關聯,dealloc還是繼續做它該做的事情

            看到以下的代碼

            - (void)viewDidUnload {

            self.detailViewController = nil; 

            self.languageNames = nil; 

            self.languageCodes = nil;

            }

            - (void)dealloc {

            [detailViewController release];

             [languageNames release]; 

            [languageCodes release]; 

            [super dealloc];

            }


            如果是先調用viewDidUnload后再調用dealloc, 那么languageNames都已經是nil了,再掉release有什么意義呢?
            原 因似乎是, 對一個viewcontroller來說,它的數據的初始化在init中,而它管理的view采用了lazy load的方式,也就是有需要的時候才會載入, 所以跟view相關的數據可以在viewDidLoad(也就是在view被載入的時候)進行初始化。當內存緊張的時候, ios會銷毀點一些view, 通過調用viewDidUnload (里面一般也只是把跟view相關的數據設為nil), 但這個時候viewcontroller本身還在, 所以它的dealloc不會被調用,除非是到了viewcontroller也被銷毀的時候

            posted @ 2012-11-23 10:41 RTY 閱讀(500) | 評論 (0)編輯 收藏

            隔上一次寫iPad app開發文章已經是10個月,那篇iPad app開發概述還不錯,曾經成為了google關鍵字“iPad app 開發”搜索的第一位,可能是大牛們都太忙于賺app store的錢了,留下我這個小蝦來寫文章。這次的文章集中與iOS的多核編程和內存管理,為什么?因為iPad 2已經是雙核CPU了!雖然iPad 1的應用已經不慢了,但大家完全可以使用蘋果的多核編程框架來寫出更加responsive的應用。

             

            多核運算

            在iOS中concurrency編程的框架就是GCD(Grand Central Dispatch), GCD的使用非常簡單。它把任務分派到不同的queue隊列來處理。開發者把任務代碼裝到一個個block里面,操作系統把這些任務代碼分派到不同的資源里去處理,一個簡單的例子來說,為什么初學者寫tableview的時候,滑動列表時總會很卡,因為很多初學者把圖片裝載放到main thread主線程去執行,例如我們要滑動暢順的話,iOS最快可以1秒內刷新60次,如何你的一個cell的文字和圖片裝載超過1/60秒的話,自然就會卡。所以一般我們會把圖片裝載這些需要多點時間的移出main thread來處理,對于用GCD來說,就是把圖片載入放到另外一個queue隊列中來異步執行,當資源準備好了后,放回到main thread中顯示出來。main thread在GCD中就是main queue。

             

            創建一個新queue隊列的代碼:

             

             

            C代碼  收藏代碼
            1. dispatch_queue_t network_queue;  
            2.   
            3. network_queue = dispatch_queue_create("com.myapp.network", nill);  

             

            例如,我們圖片讀取放到network_queue來進行異步執行

             

             

            C代碼  收藏代碼
            1. dispatch_async(network_queue, ^{    
            2.     UIImage *cellImage = [self loadMyImageFromNetwork:image_url];    
            3.     // 將圖片cache到本地    
            4.     [self cacheImage:cellImage];    
            5.     
            6.     .....    
            7.         
            8. } );  
             

             

            dispatch_async的意思就是將任務進行異步并行處理,不一定需要一個任務處理完后才能處理下一個。以上代碼loadMyImageFromNetwork的意思就是從網絡中讀取圖片,這個任務交給network_queue來處理。這樣讀取圖片的時間過長也不會阻塞主線程界面的處理。

             

            當我們處理完圖片后,應該更新界面,從queue的概念去設計,就是要將更新界面的代碼放到main queue中去,因為iOS里面永遠是主線程來刷新重畫UI。所以代碼應該為,

             

             

            C代碼  收藏代碼
            1. dispatch_async(network_queue, ^{    
            2.     UIImage *cellImage = [self loadMyImageFromNetwork:image_url];    
            3.     // 將圖片cache到本地    
            4.     [self cacheImage:cellImage];    
            5.     
            6.    // 回到主線程    
            7.    dispatch_async(dispatch_get_main_queue(), ^{    
            8.       // 顯示圖片到界面    
            9.       [self displayImageToTableView:cellImage];    
            10.    }];    
            11.         
            12. } );  
             

             

            dispatch_get_main_queue() 函數就是返回主線程,^{} 封裝的就是任務代碼,這樣嵌套方式就可以從一個隊列queue,跳到另一個queue,就是這么簡單。

             

            我們一般可以把networking有關的代碼放到一個queue,把圖片resize的代碼放到另外一個queue,處理完后更新界面,只需要嵌套跳回到 main queue。這樣加上幾行代碼,你的程序就可以利用到系統多核資源,把具體的調度工作交給了操作系統自己來分配。有了這樣的代碼,不管你的硬件是單核,雙核還是iMac的4核,甚至8核,都可以非常好地并行處理。

             

             

            內存管理

            我一直驚嘆iOS和Objective-C內存處理能力,例如iPad版本的iWork,Pages應用就是一個內存處理技術應用的鬼斧神工之作。想想256M內存的iPad,可以帶來如此的華麗的界面同時獲得如此流暢的用戶體驗,真是不簡單。原因就是iOS一直提倡開發者在有限硬件資源內寫出最優化的代碼,使用CPU最少,占用內存最小。

             

            (以下代碼適用于iOS SDK 4.1, 由于新SDK 4.2對內存使用有新改動,所以可能有不同。。。)

            1. 盡量少的UIView層

            通常我們喜歡把很多控件層(UILabel,UIButton,UIView等)一起放到一個大的UIView容器來顯示我們的內容,這個方法一般是可以的,但是如果要經常重新刷新內容的大區域界面,多數發生在iPad的應用中,這個方法會帶來過多的內存使用和動畫的延遲(比較卡),例如,scrollview的動畫比較卡,又或者,經常收到內存警告。其中一個重要原因是每個控件,特別是透明底的,會多次重新繪制(drawRect)過多。其解決辦法是,盡量將幾個控件合并到一個層上來顯示,這樣系統會減少系統調用drawRect,從而帶來性能上的提升。

             

            很簡單的一個例子,就是iNotes提供手寫功能,用戶可以在iPad屏幕上寫出不同的筆畫,開始的設計是,用戶每寫一劃,iNotes就會生成一個新的透明底UIView來保持這個筆畫,用戶寫了10筆,系統就生產了10個UIView,每個view的大小都是整個屏幕的,以便用戶的undo操作。這個方案帶來嚴重的內存問題,因為系統將每個層都保持一個bitmap圖,一個像素需要4bit來算,一個層的大小就是 4x1024x768 ~ 3M, 10個層就是 10x3M = 30M,很明顯,iPad很快爆出內存警告。

             

            這個例子最后的方案是,所有筆畫都畫在同一個層,iNotes可以保存筆畫的點進行undo操作。這樣的方案就是無論用戶畫多少筆畫,界面重畫需要的資源都是一樣的。

             

            2. 顯示最佳尺寸的圖片

            很多程序員比較懶,網絡上拿下來的圖片,直接就用UIImageView將其顯示給用戶,這樣的后果就是,程序需要一直保存著大尺寸的圖片到內存。解決辦法應該是先將圖片縮小到需要顯示的尺寸,釋放大尺寸圖片的內存,然后再顯示到界面給用戶。

             

            3. 盡量使用圖片pattern,而不是一張大的圖片

            例如,很多界面設計者喜歡在界面上放一個大底圖,但這個底圖是老是占用著內存的,最佳方案是,設計出一個小的pattern圖,然后用這個方案顯示成底圖。

             

            C代碼  收藏代碼
            1. UIImage *smallImage = [[UIImage alloc] initWithContentsOfFile:path];  
            2.   
            3. backgroundView.backgroundColor = [UIColor colorWithPatternImage:smallImage];  
            4.   
            5. [smallImage release];  
             

             

            4. 使用完資源后,立即釋放

            一般objective-c的習慣是,用完的資源要立即釋放,因為明白什么時候用完某個資源的是程序員你自己。

            例如,我們要讀較大的圖片,把它縮小后,顯示到界面去。當大圖片使用完成后,應該立即釋放。代碼如下:

             

            C代碼  收藏代碼
            1. UIImage *fullscreenImage = [[UIImage alloc] initWithContentOfFile:path];  
            2. UIImage *smallImage = [self resizeImage:fullscreenImage];  
            3.   
            4. [fullscreenImage release];  
            5.   
            6. imageView.image = smallImage;  
            7.   
            8. ......  
             

            5. 循環中大量生成的自動釋放autorelease對象,可以考慮使用autorelease pool封裝

            代碼范例:

            C代碼  收藏代碼
            1. for(UIView *subview in bigView.subviews) {  
            2.     // 使用autorelease pool自動釋放對象池  
            3.     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  
            4.   
            5.     UIImageView *imageView = (UIImageView *)subview;  
            6.       
            7.     // subview處理代碼  
            8.     .......  
            9.   
            10.     // 銷毀自動釋放對象  
            11.     [pool  drain];  
            12. }  

             自動釋放對象池把每個循環內生成的臨時對象使用完后立即釋放

             

            以上的意見是本人多年來編寫iPad/iPhone程序的經驗,另外iOS4.0的multi-tasking特性發布后,程序可以被調入后臺運行,蘋果工程師的意見是,進入后臺運行時,你的應用應該釋放掉能釋放的對象,盡量保持在16M左右,這樣別的程序運行時才不容易把你的應用擠掉。

             

            --------------------------------------------------

            太久沒有寫東西了,中文寫作能力退步了,大家別見怪,多給給意見

            posted @ 2012-11-16 06:46 RTY 閱讀(319) | 評論 (0)編輯 收藏

            一般發生在使用最新的XCode。@import url(http://m.shnenglu.com/cutesoft_client/cuteeditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);

            怎么來解決問題呢,其實

            直接一點,就是在指定Complier的時候,選擇Clang,不要選擇GCC!

            你可以試試!有問題可以咨詢我!

            posted @ 2012-11-07 06:22 RTY 閱讀(1245) | 評論 (0)編輯 收藏

            僅列出標題
            共31頁: 1 2 3 4 5 6 7 8 9 Last 
            国产精品99久久不卡| 久久婷婷色综合一区二区| 国产精品一区二区久久精品无码| 一本色综合久久| 2021国产精品久久精品| 久久免费观看视频| 青青草国产成人久久91网| 久久免费国产精品一区二区| 性欧美丰满熟妇XXXX性久久久 | 三上悠亚久久精品| 久久九九精品99国产精品| 国产精品美女久久久m| 免费观看久久精彩视频| 久久人人爽人人爽人人片av高请| 欧美黑人激情性久久| 狠狠色婷婷久久综合频道日韩 | AAA级久久久精品无码片| 性色欲网站人妻丰满中文久久不卡| 一本色道久久综合亚洲精品| 亚洲欧美日韩中文久久| 精品免费久久久久久久| 狠狠色丁香婷综合久久| 久久亚洲AV无码精品色午夜| 亚洲欧美伊人久久综合一区二区| 国内精品久久人妻互换| 午夜不卡888久久| 日韩人妻无码一区二区三区久久 | AV无码久久久久不卡网站下载| 一本一道久久精品综合| 亚洲国产精品综合久久网络| 久久久久国产精品人妻| 99久久国产亚洲高清观看2024| 久久强奷乱码老熟女| 亚洲伊人久久精品影院| 国产香蕉97碰碰久久人人| 日韩人妻无码一区二区三区久久| 国产精品美女久久久久网| 少妇久久久久久久久久| 秋霞久久国产精品电影院| 久久天天躁狠狠躁夜夜avapp| 久久777国产线看观看精品|