IOS apprentice4

1. An postfix M means the file has been modified since the last "commit" and an A means this is a file that has been added since then.

2. what is keeping these views from being deallocated?

Views are always part of a view hierachy and they will always have an owner wit ha strong reference: their superview

3. the didSelectRowAtIndexPath method will simply deselect the row with an animation, while willSelectRowAtIndexPath makes sure that you can only select rows with actual search results.

4. A nib, also called a xib, is very much like a storyboard except that it only contains the design for a single thing. That thing can be a view controller but it can also be an individual view or table view cell. A nib is really nothing more than a container for a "freeze dried" object that you can edit in Interface Builder

Xib or nib?  a xib file is compiled into a nib file that is put into your application bundle. the term inb mostly stuck for historical reasons(it stands for NeXT Interface Builder).

5: Putting symbolic constants as static let members inside a struct is a common trick in Swift. A static value can be used without an instance so you don't need to instantiate TableViewCellIdentifiers before you can use it.'

struct TableViewCellIdentifiers {
    static let searchResultCell = "SearchResultCell"
}

6:  The role of App Delegate:

The ppor AppDelegate is often abused. People give it too many responsibilities. Really, there isn't that much for the app delegate to do.

It gets a number of callbacks about the state of the app - whether the app is about to be closed, for example - and handling those events should be its primary responsiblity. The app delegate also owns the main window and the top-level view controller. Other than that, it shouldn't do much.

Some developers use the app delegat as their data model. That is just bad design. You should really have a separate class for that. Others make the app delegate their main control hub. Wrong again! Put that stuff in your top-level view controller.

If you ever see the following type of thing in someone's source code, it's a pretty good indication that the application delegate is being used the wrong way:

let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegte
appDelegate.property = " "

This happens when an object wants to get something from the app delegate. it works but it's not good architecture.

It's better to design your code the other way around: the app delegate may do a certain amount of initialization, but then it gives any data model objects to the root view controller, and hands over control. The root view controller passes these data model objects to any other controller that needs them, and so on.

This is also called "dependecy injection"

7. change background color of cell: each table view cell have a "selectedBackgroundView" property

awakeFromNib() method is called after this cell object has been loaded from the nib but before the cell is added to the table view. You can use this method to do additional work to prepare the object for use. That's perfect for creating the view with selection color.

8: There are different types of crashes, such as SIGABRT, EXC_BAD_ACCESS, EXC_BAD_INSTRUCTION

If your app crashes with EXC_BAD_INSTRUCTION or SIGABRT, the Xcode debugger will often show you an error message and where in the code the crash happens

if Xcode thinks the crash happened on AppDelegate(not very useful!), enable the Exception Breakpoint to get more info

if the app crashes with a SIGABRT but there is no error message, then disable the Exception Breakpoint and make the app crash again.(Alternatively, click the "Continue program execution" button from the debugger toolbar a few times, that will also show the error message.)

An EXC_BAD_ACCESS error usually means something went wrong with your memory management. An object  may have been "released" one time too many or not "retained" enough. With Swift these problems are mostly a thing of the past because the compiler will usually make sure to do the right thing. However, it's still possible to mess up if you're talking to Objective-C code or low-level API's

EXC_BREAKPOINT is not an error, the app has stopped on a breakpoing, the blue arrow pointing at the line where the app is paused. You set breakpoints to pause your app at specific places in the code, So you can examine the state of the app inside the debugger. The "Continue program execution" button resumes the app.

9: 

searchResults.sort({ result1, result2 in 
    return result1.name.localizedStandardCompare(result2.name) == NSComparisonResult.OrderedAscending})

// easier way to implement using trailing closure, no longer return
searchResults.sort { $0.name.localizedStandardCompare($1.name) == NSComparisonResult.OrderedAscending }

Operator overloading: 

func < (lhs: SearchResult, rhs: SearchResult) -> Bool {
    return lhs.name.localizedStandardCompare(rhs.name) == NSComparisonResult.OrderedAscending }
// creating a function named < 

thus, above can be written as

searchResults.sort($0 < $1) 
// or even simpler
searchResults.sort(<)

10: parameters in URLs are separated by & sign. space is represented by + sign or %20

string.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)

ASCII and Unicode are the two most common encodings

 

11: Each process inturn is given a bit of CPU time to do its work. The process splits up that time among its threads. Each thread typically performs its own work and is as independent as possible from the other threads within that process.

An app can have multiple threads and the CPU switches between them

The main thread is the app's initial thread and from there all the other threads a re spawned. The main thread is responsible for handling user interface events and also drawing the UI. Most of app's activites take place on the main thread. Whenever the user taps a button in app, it is the main thread that performs action method.

If one action method takes more than a fraction of a second to run, then doing all these computations on the main thread is not a good idea for the reasons you saw earlier.

NEVER BLOCK THE MAIN THREAD! MAKE IT ASYNCHRONOUS

 12: Rather than making your own threads, IOS has several more conveniet ways to start background processes. such as queues and Grand Central Dispatch. GCD greatly simplifies tasks that require parallel programming.

GCD has a number of queues with different priorities. To perform a job in the background, you put it in a closure and then give that closure to a queue and forget about it. It's as simple as that. 

UIKit has a rule that all UI code should always be performed on the main thread. And This is important.

Accessing the samte data from multiple threads can create all sorts of misery, so the designers of UIKit decided that changing gthe UI from other threads would not be allowed. That means you cannot reaload the table view from within this closure because it runs on a queue that is backed by a thread other than the main thread.

As it happens, there is also a so-called "main queue" that is associated with the main thread. If you need to do anything on the main thread from a background queue, you can simply create a new closure and schedule that on the main queue

13: Review of closure

A closure does not get performed right away, it is stored in "closure object" and can be performed at a later point, even more tha nonce.

That's exactly what NSURLSession does: it keeps hold of the "completion handler" closure and only performs it when a response is received from the web server or when a network error occurs

a closure typically looks like this

let dataTask = session.dataTaskWithURL(url, completionHandler: {
    data, response, error in
        // source code
})

the form of closure is always:

{
    parameters in 
    your source code
}
// or without parameters
{
    your source code
}

Thanks to Swift's type inference you don't need to specify the data types of the parameters. However, you can still write them in full if you wanted to:

let dataTask = session.dataWithURL(url, completionHandler: {
    (data: NSData!, response: NSURLResponse!, error: NSError!) in
    // source code
})

if you don't care about ta particular parameter you can substitute it with _, the wildcard symbol:

let dataTask = session.dataTaskWithURL(url, completionHandler: {
    data, _, error in
})

if a closure is really simple, you can leave out the parameter list and use $0, $1, and so on as the parameter names.

let dataTask = session.dataTaskWithURL(url, completionHandler: {
    println("My parameters are \($0), \($1), \($2)")
})

if a closure is the last parameter of a method, you can use trailing syntax to simplify the code a little

let dataTask = session.dataTaskWithURL(url){
    data, response, error in
}

Closures are also useful for initializing objects and lazy loading:

lazy var dateFormatter: NSDateFormatter = {
    let formatter = NSDateFormatter()
    formatter.dateStyle = .MediumStyle
    formatter.timeStyle = .ShortStyle
    return formatter
}()

This is a common trick for placing complex initialization code right next to the variable declaration.

You can supply the name of a method or function when a closure is expected, as long as the parameters match:

let dataTask = session.dataTaskWithURL(url, completionHandler: myCompletionHandlerMethod)

func myCompletionHandlerMethod(data: NSData!, response!, error: NSError!){
}

One final thing to be aware of with closures is that they "capture any variables" used inside the closure, including self. This can create ownership cycle, often leading to memory leaks. To avoid this, you can supply a capture list:

let dataTask = session.dataTaskWithURL(url){
    [weak self] data, response, error in
}

 14: NSURLSession is a closure-based API, meaning that instead of making a delegate for it, you give it a closure containing the code that should be performed once the response from the server has been received. NSURLSession calls this closure the "completion handler"

15: since UI updating is always in main thread. so we need to wrap the reloding of the table view into dispatch_async() on the main queue

dispatch_async(dispatch_get_main_queue()){
    self.isLoading = false
    self.tableView.reloadData()
}

16: segmented control: is used to pick on option out of multiple choices.

17: an extension can be used to extend the functionality of an existing class without having to subclass it. This works even for classes from the system frameworks

UIImageView doesn't have built-in support for downloading images, but this is a very common thing to do in apps.

add a new file using swilf file template. and name it UIImageView+DownloadImage.swift

import UIKit

extension UIImageView {
    func loadImageWithURL(url: NSURL) -> NSURLSessionDownloadTask {
        let session = NSURLSession.sharedSession()
        
        // 1
        let downloadTask = session.downloadTaskWithURL(url, completionHandler: {[weak self] url, response, error in
            if error == nil && url != nil {
                // 3
                
                if let data = NSData(contentsOfURL: url) {
                    if let image = UIImage(data: data) {
                        dispatch_async(dispatch_get_main_queue()) {
                            if let strongSelf = self {
                                strongSelf.image = image
                            }
                        }
                    }
                }
            }
        })
        
        downloadTask.resume()
        return downloadTask
    }
}

after obtaining a reference to the shared NSURLSession, you create a download task. This is similiar to data task but it saves the downloaded file to a temporary location on disk instead of keeping it in memory

Inside the completion handler for the download task you're given a URL where you can find the downloaded file(this URL points to a local file rather than an internet address). Of course you must also check the error is nil before you continue.

With this local URL you can load the file into an NSData object and then make an image from that. It's possible that construing the UIImage fails, when what you downloaded was not a valid image but a 404 page or something else unexpected. As you can tell, when dealing with networking code you need to check for errors every step of the way

Once you have the image you can put it into the UIImageView's image property. Because this is UI code you need to do this on the main thread.

18. After creating the download task you can resume() to start it, and then return the NSURLSessionDownloadTask object to the caller, why return it? That gives the app the opportunity to call cancel() on the download task.

19: Presentation controller API, to pop up detail screen. use Dynamic Type to change the fonts based on the user's preferences. draw gradients with Core Graphics, and make cool keyframe animateions.

it's called a presentation controller, but it is not a view controller. Only those with "view" in their name

a presentation controller is an object that "controls" the presentation of something

20: When you put background images on a button in Interface Builder, they always have to fit the button exactly. that works fine in many cases, but it's more flexible to use an image that can stretch to any size.

21: using === to compare the same object. == would check whether both variables refer to objects that are considered equal, even if they are not the same object.

22: Animation: Core Animation, UIView animation, and keyframe animation

23: trait collection: a collection of trats, where a trait can be:

  the horizontal size class

  the vertical size class

  the display scale(is this a Retina screen or not?)

  the user interface idiom(is this an iPhone or iPad?)

whenever one or more of these traits change, for whatever reason, UIKit calls willTransitionToTraitCollection(withTransitionCoordinator) to give the view controller a chance to adapt to the new traits.

the size class allows to design a single storyboard that can be used on both Iphone and IPad, but what exactly are size classes?

Well, there are two of them, a horizontal one and a vertical one, and each can have two values.: Compact and Regular.

24: controller containment, now view controllers are allowed to be part of other view controllers.

25: associatd value

转载于:https://www.cnblogs.com/glee/p/4497028.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iOS Apprentice》是一本广受欢迎的iOS开发教程书籍,提供了丰富的实战项目和详细的讲解,帮助读者从零开始学习iOS开发技能。该书以实例为主,通过开发实际应用程序的方式,让读者逐步掌握iOS开发的基础知识和技巧。 这本书的作者采用了直观、易懂的方式编写,使初学者也能轻松理解。它适用于没有任何开发经验的初学者,以及有一些基础知识的开发人员。书籍中的每个项目都是从头开始构建的,从设计界面到编写代码,再到测试和调试,每一步都有详细的指导和解释。通过跟随书中的教程,读者将学会使用常见的iOS开发工具和技术,如Xcode、Swift编程语言、界面构建、故事板、Core Data、网络请求等,同时还能学会一些常用的设计模式和最佳实践。 《iOS Apprentice》还提供了多种主题和功能的实战项目,如任务清单、图片浏览、音乐播放器等,通过完成这些项目,读者可以学会开发各种类型的iOS应用。书中的练习和挑战也有助于读者巩固所学的知识,并自己动手实践。 总之,《iOS Apprentice》是一本非常实用和全面的iOS开发教程书籍,适合想要学习iOS开发的人。它通过项目实战的方式,帮助读者快速入门iOS开发,并提供了丰富的示例和练习,让读者能够熟练掌握iOS开发的各个方面。无论你是初学者还是有一定经验的开发者,这本书都能为你提供有价值的学习资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值