溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

iOS優化內存,提升性能 之四

發布時間:2020-06-27 08:49:40 來源:網絡 閱讀:599 作者:iKingLai 欄目:移動開發

UI中顯示和隱藏view


UI中顯示和隱藏view,需要用到的內存操作很少。但是,這個和iOS app的性能和用戶體驗有關。


view顯示或隱藏時,在view controller中有4個主要的方法來表示view的不同狀態。


§ viewWillAppear:在view顯示之前會調用這個方法。只有這個方法調用完之后,才會顯示你的view。為了給應用創造一個很好的用戶體驗,在這里做的計算最好要非常的快。否則,用戶會感覺你的導航和動畫比較弱。一個好的做法是設置view的屬性(例如,背景色或文本顏色)。


例如,用戶按下返回按鈕返回到view A。但是,在view A的viewDidAppear方法內部,有一個耗時的計算。這個計算結果可能會花幾秒鐘,但是同時UI線程會被阻塞來處理view A的內部邏輯,同時view A也無法顯示。


  • viewDidAppear:在view顯示之后,這個方法會被調用,所以你可以把你的邏輯處理放在這里。但是,如果在它執行完后,你的處理過程會改變view,用戶可能會感到迷惑,這不是一個好的用戶體驗。


例如,你有一個排序算法來對你的table view進行排序。當用戶看到view A時,舊的table還在顯示。然后突然所有的的rows發生了變化,而沒有任何的警告或是解釋發生了什么事情。


  • viewDidDisappear:在view從UI消失之前會調用這個方法。任何屬于這個view的,你想要顯示給用戶的,都應該放在這里。注意在這里你不應該放置太多邏輯處理的代碼。如果你在這里放了很多的邏輯處理代碼,那么顯示一個新的view就會花很多時間。


沒有什么硬性規則說你應該把邏輯處理過程放在什么地方。我向你介紹了所有的基本的概念,你可以使用他們創建比較好的用戶體驗和性能。



對象拷貝


你為什么需要知道對象拷貝以及為什么需要它呢?拷貝一個對象是非常有用的,如果你不想改變舊的對象,因為它可能影響到其他部分程序。在某些情況下,你根本不能修改對象,所以你只能拷貝這個對象的內容,然后再進行修改。


淺拷貝和深拷貝


在Objective-C中,淺拷貝實際上和retaining是一樣的。因為淺拷貝是拷貝一個對象的指針到一個新的變量中,在淺拷貝和retaining之間是沒有什么不同的。


另一方面,深拷貝意味著你會實際創建一個新的對象,然后從舊的對象中拷貝所有的數據和實例變量到新的對象中。


為了演示淺拷貝和深拷貝在Objective-C之間的不同,考慮下面的代碼:


Shallow copying:

- (void)setMyObj:(NSObject *)newObj {

   if (newObj != myObj) {

       myObj = newObj;

   }

}

Deep copying:

- (void)setMyObj:(NSObject *)newObj {

   if (newObj != myObj) {

       myObj = [newObj copy];

   }

}


在第一種情況下,你把變量的值賦值給一個新的對象然后retain這個對象。在Objective-C中,這就是淺拷貝。在深拷貝例子中,代碼實際上拷貝了newObj的值和實例變量到myObj。


實現一個深拷貝


如果你確實需要一個深拷貝,你必須了解對象的整個層次結構。

  • 你需要創建一個新的對象。

  • 把舊對象的所有的實例變量拷貝到新對象中。

  • 如果實例變量是基本數據類型,比如float,int或double,你只需要拷貝他們的值。Boolean不是基本類型,但是你也只需要拷貝它的值即可。

  • 對于每一個指針類型的實例變量,你同樣要拷貝它們的實例變量。

  • 這個過程需要一直持續,直到結束。


這個過程可能很長,而且很難實現。一些內置的對象和庫不支持深拷貝。因此,你需要在淺拷貝和深拷貝之間進行比較。例如,你不想深拷貝一個delegate,像前面介紹的,它會導致循環引用,即對象A擁有對象B,對象B擁有對象A。更進一步的,你通常不應該拷貝你的delegate,因為你最終只是想要回調它,而不是創建它。


這是一個混合了淺拷貝和深拷貝的例子:


@interface Item : NSObject {

  1. NSString *itemName;

  2. CGFloat price;
    id delegate;

}

@property (nonatomic, copy) NSString *itemName;

@property (nonatomic, weak) CGFloat price;

@property (nonatomic, weak) id delegate;


@end


在這個例子中,你可以看到有3個實例變量。第一個是itemName(這是一個指針對象),第二個是一個基本數據類型,第三個是一個delegate。


iOS優化內存,提升性能 之四

如圖7-8,delegate對象在原始的item和新的item中將保持一樣。itemName對象將會被拷貝,有一個新的內存地址(0x9124代替了0x8028),但是都有同樣的值“egg”。對于基本數據類型,例如price,將會被拷貝,它沒有內存地址。


在對象中實現copy方法


為了實現對象的深拷貝,你通常需要重寫copyWithZone:方法。當向一個對象發送copy消息,這個方法會被調用。這里有一些重寫這個方法的代碼。你需要用alloc和init創建一個新的對象,然后使用set方法給實例變量設值。


- (id)copyWithZone:(NSZone *)zone {
   Item *copy = [[Item allocWithZone: zone] initWithName:self.itemName];

   copy.price = self.price;
   copy.delegate = self.delegate;
   return copy;

}


就像前面所說的,在你的item class中如果有自定義的實例變量,你需要為它實現copy方法。在我的例子中,為了簡單起見,代碼沒有創建一個新的itemName對象。







向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女