精华内容
下载资源
问答
  • ios 初级开发A beginner friendly approach to software architecture. 初学者友好的软件体系结构方法。 In this article I describe part of my journey as a junior iOS developer and some of the issues I ...

    ios 初级开发

    A beginner friendly approach to software architecture.

    初学者友好的软件体系结构方法。

    In this article I describe part of my journey as a junior iOS developer and some of the issues I faced and the solutions I came up with after some research.

    在本文中,我描述了作为一名初级iOS开发人员的过程中的一部分旅程,以及我经过研究后遇到的一些问题和解决方案。

    背景 (Background)

    I began my journey as an iOS developer back in 2015 in a company that developed smart-watches and had a companion application to manage the watch both for Android and iOS. The project I inherited from “senior” iOS developers was built using Objective-C and had at least 200 files, most of them were UIViewController implementations for the multiple screens the app had. Build times were awful and the project had a really hard time scaling, objects had a lot of responsibilities and requests from upper management to add new features took way too much time and often seemed impossible. Looking for help in the iOS dev community I found that what I was facing at the time was very common among junior devs and it had a name, MassiveViewController.

    我在2015年作为一家iOS开发人员开始了自己的旅程,当时该公司开发了智能手表,并拥有一个配套应用程序来管理Android和iOS手表。 我从“高级” iOS开发人员继承的项目是使用Objective-C构建的,并且至少具有200个文件,其中大多数是该应用程序具有多个屏幕的UIViewController实现。 构建时间很糟糕,项目很难扩展,对象承担很多责任,高层管理人员添加新功能的请求花费了太多时间,而且通常看起来是不可能的。 在iOS开发人员社区中寻求帮助时,我发现我当时面对的情况在初级开发人员中非常普遍,并且它的名称为MassiveViewController。

    Apple encourages developers to use MVC in iOS apps, by its deep integration in UIKit. Following Apple’s MVC, junior developers wrongly put everything in the UIViewController like view layout, view updates, model manipulation, data access, networking, etc.

    苹果通过与UIKit的深度集成,鼓励开发人员在iOS应用中使用MVC。 遵循Apple的MVC,初级开发人员错误地将所有内容放入UIViewController中,例如视图布局,视图更新,模型操纵,数据访问,联网等。

    Looking for a solution, I became familiar with popular architectural patterns in the presentation layer that vary from MVC such as MVP and MVVM. As many junior devs in the community, I thought that the MV* variations mentioned before would fix my problem. And as other junior developers I made the mistake of trying to fit every object in the project in one of the categories that compose the acronym of the pattern of choice, i.e using MVVM, objects either were a Model, a ViewModel or a View.

    在寻找解决方案时,我熟悉了表示层中流行的架构模式,这些模式与MVC(例如MVP和MVVM)不同。 与社区中的许多初级开发人员一样,我认为前面提到的MV *版本可以解决我的问题。 和其他初级开发人员一样,我犯了一个错误,即试图将项目中的每个对象放入组成选择模式首字母缩写的类别之一中,即使用MVVM,对象是模型,视图模型或视图。

    Other mistake I made was to give objects too many responsibilities, for instance ViewModels ended up being in charge of networking, data access, model manipulation, etc, just like using a UIViewController with MVC. Later I learnt that not all objects would fit it in one of those categories and that responsibilities should be limited.

    我犯的另一个错误是赋予对象太多的责任,例如ViewModels最终负责网络,数据访问,模型操作等,就像将UIViewController与MVC一起使用一样。 后来我了解到,并非所有对象都适合这些类别之一,并且应该限制责任。

    So after learning from my mistakes and started using the patterns the right way I realized that even though the patterns helped my code to be more readable and objects in the project had fewer responsibilities than before, they didn't seemed to really fix the core issue, maintainability was still difficult and adding new features a nightmare. This is because the problem wasn’t in how the UI and Presentation were talking to each other, but in how the whole software was structured, in other words the problem I was facing was with the software architecture.

    因此,从错误中吸取教训并以正确的方式开始使用模式后,我意识到,即使这些模式使我的代码更具可读性,并且项目中的对象比以前少了责任,但它们似乎并没有真正解决核心问题,可维护性仍然很困难,并且增加了新功能。 这是因为问题不在于UI和Presentation如何彼此交谈,而在于整个软件的结构方式,换句话说,我所面临的问题是软件体系结构

    一些研究 (Some Research)

    那么什么是MVC? (So What is MVC?)

    Model View Controller (MVC) was introduced back in 1979 by Trygve Reenskaug in the Model View Controller Report. Reenskaug defines MVC in this article as follows.

    模型视图控制器(MVC)于1979年由Trygve Reenskaug在“模型视图控制器报告”中引入。 Reenskaug在本文中对MVC的定义如下。

    MVC was conceived as a general solution to the problem of users controlling a large and complex data set.

    MVC被认为是解决用户控制大型和复杂数据集问题的通用解决方案。

    The essential purpose of MVC is to bridge the gap between the human user’s mental model and the digital model that exists in the computer. The ideal MVC solution supports the user illusion of seeing and manipulating the domain information directly. The structure is useful if the user needs to see the same model element simultaneously in different contexts and/or from different viewpoints. The figure below illustrates the idea.

    MVC的基本目的是弥合人类用户的心理模型与计算机中存在的数字模型之间的鸿沟。 理想的MVC解决方案支持用户直接查看和操作域信息的错觉。 如果用户需要在不同的上下文中和/或从不同的角度同时看到相同的模型元素,则此结构很有用。 下图说明了这个想法。

    Image for post
    Fig.1 Trygve Reenskaug’s MVC — Diagram by Trygve Reenskaug
    图1 Trygve Reenskaug的MVC — Trygve Reenskaug的图表

    If we analyze the diagram above MVC refers to the interaction between the user, an input tool, a process and an output. MVC seems like a very generic concept, it’s so generic that it can apply to almost any architecture that isn’t total spaghetti code. But nowadays applications are not only composed of a view like a text-editor, a model like a text, and a controller to manage the interaction. Applications now hold complex behaviors and processes, need remote data access, analytics and what not.

    如果我们分析上面的图,MVC是指用户,输入工具,过程和输出之间的交互。 MVC似乎是一个非常通用的概念,它是如此通用,几乎可以应用于任何不是全部意大利面条式代码的体系结构。 但是如今,应用程序不仅由诸如文本编辑器的视图,诸如文本的模型以及用于管理交互的控制器组成。 应用程序现在具有复杂的行为和流程,需要远程数据访问,分析以及其他功能。

    Essentially MVC refers to what today we know as the presentation part of an application. Therefore MVC, MVP and MVVM only solve the way we structure the presentation of an application, each in a different way.

    本质上,MVC指的是今天我们所知道的应用程序的表示部分。 因此,MVC,MVP和MVVM仅以不同的方式解决了构建应用程序表示的方式。

    更多研究 (More Research)

    I knew that there had to be a way to design software that wasn’t so hard to maintain. So I dived into lots of software architecture literature, Clean-Architecture by Uncle Bob, Hexagonal Architecture, Layered Architecture and Microservices. Throughout my readings I can conclude that they are essentially all the same. Bear with me here, each architecture is different from each other and serve different purposes. This is in the surface though, deep down they intend the same goal, which is to separate responsibilities and establish a standard way of communication between its components, improve maintainability and scalability and reduce development time.

    我知道必须有一种设计软件的方法,它并不很难维护。 因此,我深入研究了许多软件体系结构文献,包括Bob叔叔的Clean-Architecture,六角体系结构,分层体系结构和微服务。 在阅读过程中,我可以得出结论,它们基本上是相同的。 在这里忍受我,每种体系结构互不相同,并且服务于不同的目的。 尽管从表面上看,他们的内在目的是相同的目标,即分离职责并建立组件之间的标准通信方式,提高可维护性和可伸缩性并减少开发时间。

    那么,如何从MassiveViewController转到易于维护的可扩展项目project? (So, how do I go from MassiveViewController to a scalable easy to maintain project 🚀?)

    After all my research, I had some knowledge to build my own implementation of a software architecture and solve my problem. I found that a clean-layered- modular oriented architecture was the way to go, so I did that.

    经过所有的研究,我掌握了一些知识来构建自己的软件体系结构实现并解决了问题。 我发现必须采用干净的面向分层模块的架构,所以我做到了。

    The architecture I came up with focuses on building software by composing multiple independent reusable modules, a practice that many developers use.

    我提出的体系结构专注于通过组合多个独立的可重用模块来构建软件,这是许多开发人员使用的一种做法。

    好处 (Benefits)

    This approach lets developers built software that is easy to test, maintain and scale. On the business side, this architecture helps developers deliver applications in small chunks which increases speed of development since multiple developers can build different parts of the software simultaneously, it even allows for software to be developed with no need to wait for the UI to be designed. Ultimately this means better productivity which translates to our clients using higher quality products, better costumer retention and maybe even increased profitability.

    这种方法使开发人员可以构建易于测试,维护和扩展的软件。 在业务方面,此架构可帮助开发人员以小块形式交付应用程序,这可以提高开发速度,因为多个开发人员可以同时构建软件的不同部分,它甚至允许开发软件而无需等待UI的设计。 。 最终,这意味着更高的生产率,这可以转化为使用更高质量产品的客户,更好的客户保留率,甚至可能提高利润率。

    潜水之前 (Before diving in)

    This is not a silver bullet. Every software behaves differently and is designed to solve a specific need, hence each software must have its architecture designed to fit its purpose. Nonetheless this simple architecture which is based on widely popular architectural patterns, should fit most applications.

    这不是灵丹妙药。 每个软件的行为各不相同,旨在满足特定需求,因此,每个软件都必须具有适合其目的的体系结构。 但是,这种基于广泛流行的架构模式的简单架构应该适合大多数应用程序。

    结构体 (Structure)

    Most applications are composed of multiple features that use a database, some sort of storage and third party services.

    大多数应用程序由使用数据库,某种存储和第三方服务的多种功能组成。

    特征 (Features)

    A Feature refers to a specific set of tasks and use cases of an application, i.e Messages in a social networking app. Every Feature must live in its own module (think of a sandbox) so it can be replaced by other implementations that perform the same required tasks, for instance replace the Messages Feature with a new version with new UI and fancy animations without breaking the whole app.

    功能是指应用程序(即社交网络应用程序中的Message)的一组特定任务和用例。 每个功能都必须存在于其自己的模块中(就像沙盒一样),以便可以由执行相同必需任务的其他实现替换它,例如,用具有新UI和精美动画的新版本替换Message s Feature ,而不会破坏整体应用程式。

    分解功能 (Breaking down a Feature)

    A Feature like Messages is composed of small pieces that do a specific task, these pieces are what users actually interact with.

    诸如消息之类的功能由执行特定任务的小部分组成,这些部分是用户实际与之交互的部分。

    Taking the previous Messages example into consideration, let's analyze a real world app like iMessage.

    考虑到前面的Messages示例,让我们分析一个像iMessage这样的真实应用程序。

    Image for post
    Fig.2 — iMessage in iOS7 Images by Apple Inc.
    图2-Apple Inc.在iOS7图像中的iMessage

    If we break it down we will find that the messaging feature of an app is probably composed by some of the next parts:

    如果将其分解,我们将发现应用程序的消息传递功能可能由以下几个部分组成:

    • ChatList

      聊天清单
    • NewChat

      新聊
    • Chat

      聊天室

    Through this exercise we realize that the Messages Feature is only a concept that encapsulates a lot of parts that execute specific tasks.

    通过本练习,我们意识到消息功能只是一个概念,它封装了许多执行特定任务的部分。

    Image for post
    Fig.3 Messages Feature
    图3消息功能

    Some Features may also contain Sub-Features. Sub-Features are parts of a Feature that may render too complex to be implemented in a single module.

    某些功能可能还包含子功能。 子功能是功能的一部分,可能过于复杂而无法在单个模块中实现。

    Since Sub-Features are Features, they also live in their own module. Take the Chat component in iMessage as an example, entering in a Chat we might find the following.

    由于子功能是功能,因此它们也存在于自己的模块中。 以iMessage中的“聊天”组件为例,输入“聊天”可能会发现以下内容。

    Image for post
    Fig. 4 — iMessage chat in iOS7 Images by Apple Inc.
    图4 – Apple Inc.在iOS7 Images中的iMessage聊天

    As we can see it isn’t just a list of messages, it contains tasks to send voice messages, video, images and what not. The Chat component seems large and we may consider it as a Sub-Feature, thus it may also contain components like MessagesList and SearchMessage and other Sub-Features such as Camera which might be used to take pictures and then send them. So the Chat Sub-Feature might render as follows.

    我们可以看到,它不仅是消息列表,还包含发送语音消息,视频,图像等的任务。 聊天组件似乎很大,我们可以将其视为子功能,因此它可能还包含MessagesList和SearchMessage等组件以及其他子功能(例如Camera),可用于拍照然后发送。 因此,聊天子功能可能会呈现如下。

    Image for post
    Fig.5 Chat Sub-Feature
    图5聊天子功能

    架构 (The architecture)

    Software architecture is all about communication & responsibilities.

    软件体系结构是关于沟通和责任的。

    Now that we understand how a feature is composed we may start thinking of a more generic diagram to represent the architecture. In this section we will see each module in detail with an example.

    现在我们了解了功能的组成方式,我们可以开始考虑使用更通用的图来表示体系结构。 在本节中,我们将通过示例详细介绍每个模块。

    域:业务逻辑 (Domain: Business Logic)

    Business logic such as Use Cases and Models are defined all together in a separate very low level single module named Domain.

    诸如用例和模型之类的业务逻辑在一个单独的名为Domain的非常底层的单独模块中一起定义。

    Use Cases should contain the business logic actual implementation, here you should manipulate your models, access data or storage all through interfaces defined in the Domain module. The Domain module must only depend on the chosen programming language’s base framework and some interfaces needed to perform its tasks. For example in case we were using Swift, the Domain module should only depend on Foundation, though there’s one exception.

    用例应该包含业务逻辑的实际实现,在这里您应该通过域模块中定义的接口来操纵模型,访问数据或存储。 域模块必须仅取决于所选编程语言的基本框架以及执行其任务所需的某些接口。 例如,在我们使用Swift的情况下,尽管有一个例外,但Domain模块应该仅取决于Foundation。

    The exception

    例外

    A Use Case works like a black box, it receives an input and then manipulates models and other objects to perform a specific task. When finished, it returns its outputs to the interested parties. When asynchronously returning outputs callbacks and closures may be easier to use but be careful if you end up using nested closures as they could cause retain-cycles (if you use classes for your Use Cases), retain-cycles affect your app’s performance and may even cause it to crash. Which is why we prefer to use functional reactive programming and the Observer design pattern. Therefore we recommend that ‘execute’ methods should publish results to observers via a subscription. You could use KVO from Cocoa or frameworks such as RxSwift, Combine or whatever framework for FRP you like. So in this case Domain can also depend on Combine or the framework you choose.

    用例就像黑盒子一样工作,它接收输入,然后操纵模型和其他对象来执行特定任务。 完成后,它将其输出返回给感兴趣的各方。 当异步返回输出回调和闭包可能更易于使用,但如果最终使用嵌套闭包,则要小心,因为它们可能会导致保留周期(如果您将用例用于类),则保留周期会影响应用程序的性能,甚至可能导致它崩溃。 这就是为什么我们更喜欢使用函数式React式编程和Observer设计模式的原因。 因此,我们建议“执行”方法应通过订阅 结果发布观察者 。 您可以使用来自Cocoa的KVO或RxSwift,Combin等框架或任何您喜欢的FRP框架。 因此,在这种情况下,Domain也可以取决于Combine或您选择的框架。

    Image for post
    Fig.6 Domain Module
    图6域模块

    介面 (Interfaces)

    Interfaces, or protocols in Swift, serve as blueprints or contracts that specify a behavior for objects to implement. This contracts allow objects to communicate with other objects that expect this interfaces as dependencies without creating tight coupling, this also helps to avoid inheritance when using classes.

    Swift中的接口或协议用作指定要实现的对象行为的蓝图或合同。 该协定允许对象与希望将此接口作为依赖项的其他对象进行通信,而无需创建紧密耦合,这也有助于避免在使用类时进行继承。

    In the Domain module we use interfaces to communicate UseCases with objects outside the module (to avoid module dependency). Objects we may want to communicate with include objects responsable for data access and maybe some other objets for different tasks such as analytics and what not.

    在域模块中,我们使用接口将UseCases与模块外部的对象进行通信(以避免模块依赖性)。 我们可能要与之通信的对象包括负责数据访问的对象,以及可能用于诸如分析之类的不同任务的其他对象。

    (Example)

    Following the iMessage example we may have a SendTextMessageUseCase which only job would be to send a message with text. We may write it as follows:

    在iMessage示例之后,我们可能会有一个SendTextMessageUseCase,唯一的工作就是发送带有文本的消息。 我们可以这样写:

    This is a very simple Use Case example that adds the provided Message to a database through an object that conforms to MessageRepository protocol. In this example we use a Model, a Use Case and a Repository. The idea behind the Use Case is that you should write your business logic inside the execute method and return whatever output it produces to the caller once it finishes. This way we isolate business logic from UIViewControllers or other classes which lets us reuse code in other modules or even other applications.

    这是一个非常简单的用例示例,该示例通过符合MessageRepository协议的对象将提供的Message添加到数据库中。 在此示例中,我们使用模型,用例和存储库。 用例背后的想法是,您应该在execute方法内编写业务逻辑,并在完成后将其产生的任何输出返回给调用方。 这样,我们将业务逻辑与UIViewControllers或其他类隔离开来,这使我们可以在其他模块甚至其他应用程序中重用代码。

    特征 (Feature)

    An app will have multiple Feature modules. As mentioned before a Feature is composed of small pieces in charge of performing a specific set of tasks. The Feature will grab its logic from the Domain module, so all it should contain are UI & Presentation related objects.

    一个应用程序将具有多个功能模块。 如前所述,功能由负责执行一组特定任务的小部分组成。 该功能将从域模块中获取其逻辑,因此它应包含的都是与UI和Presentation相关的对象。

    In UIKit projects:

    在UIKit项目中:

    • UIViewControllers

      UIViewControllers
    • UIViews

      UIViews
    • UINavigationControllers

      UINavigationControllers
    • Xibs

      锡伯斯
    • Delegates

      代表们
    • Routers **

      路由器**
    • ViewModels / Presenters *

      ViewModels / Presenters *

    In SwiftUI projects:

    在SwiftUI项目中:

    • Views

      观看次数
    • ViewModels

      视图模型
    • Routers **

      路由器**

    *This should be present on your Feature module whether you use MVVM or MVP. Though if you prefer to use MVC there’s no need to add this files, you can use ViewControllers to stitch your logic (Domain), networking & database operations (Data) with your UI&Presentation.

    *无论使用MVVM还是MVP,此功能都应显示在功能模块上。 尽管如果您更喜欢使用MVC,则无需添加此文件,但是可以使用ViewControllers通过UI&Presentation来缝合逻辑(域),网络和数据库操作(数据)。

    ** Depends on how you manage your routing logic.

    **取决于您如何管理路由逻辑。

    Image for post
    Fig.7 Feature Module
    图7功能模块

    This is a very simple module since it only holds UI&Presentation related files. In the example shown we used MVVM, the Model part comes from the Domain which the ViewModel takes from, the View is represented by the ViewController (which receives inputs from its underlaying view and manages its lifecycle, UIKit only) and at last the ViewModel which manipulates Use Cases from Domain on ViewController’s disposal.

    这是一个非常简单的模块,因为它仅包含与UI&Presentation相关的文件。 在所示的示例中,我们使用了MVVM,Model部分来自ViewModel所来自的Domain,View由ViewController表示(ViewController从其底层视图接收输入并管理其生命周期,仅UIKit),最后是ViewModel在ViewController的处置下,从Domain操纵用例。

    Routing and navigation is up to you, you may choose to use a Router or not, since it belongs to UI & Presentation how we implement it doesn’t really affect the architecture, more on this later.

    路由和导航由您决定,您可以选择是否使用路由器,因为它属于UI&Presentation,我们如何实现它并不会真正影响体系结构,稍后将对此进行详细介绍。

    Keep in mind that the green box is only a representation, it may contain a lot of Single Component boxes since each of those represent a ‘part’ of the Feature like ChatsList, MessagesList or Camera.

    请记住,绿色框只是一种表示形式,它可能包含很多“单个组件”框,因为每个“单个组件”框都代表“功能”的“一部分”,例如ChatsList,MessagesList或Camera。

    数据与第三方 (Data & Third Parties)

    Data module contains DataModels, DataModels exist in a 1:1 relationship with Models in Domain, Mappers help DataModels be mapped into Models. Repositories must only return Models. Under the Bridge Pattern, Repositories are defined as objects that encapsulate data access.

    数据模块包含数据模型,数据模型与域中的模型以1:1关系存在,映射器帮助数据模型映射到模型中。 存储库只能返回模型。 在桥接模式下,存储库定义为封装数据访问的对象。

    Interfaces (protocols) describe a contract between objects to communicate. In simpler words protocols specify all the properties and methods a type must implement to be able to communicate with its dependees in any module. In this case as data interfaces will also be used in the Domain module by UseCases, they must be declared in the Domain module to ensure independency between modules.

    接口 (协议)描述了对象之间进行通信的契约。 用简单的话来说,协议指定类型必须实现的所有属性和方法,以使其能够与任何模块中的依赖者进行通信。 在这种情况下,UseCases还将在域模块中使用数据接口,因此必须在域模块中声明它们,以确保模块之间的独立性。

    For example if Type A implements Interface S and Type B also implements S, this means that Type A and B should behave the same in eyes of the Domain module and this also means that both implementations are interchangeable.

    例如,如果类型A实现接口S,类型B也实现S,则这意味着类型A和B在域模块的作用下应该相同,这也意味着这两种实现是可互换的。

    Image for post
    Fig.8 Data module interacting with other modules
    图8数据模块与其他模块的交互

    Interfaces in this example:

    本示例中的接口:

    • <Repository>: Defines a set of methods a type must implement to execute data related tasks required by a set of Use Cases. We should use one repositories for each model as a rule, having a single repository using generics gets complicated and it’s not recommend since each model may need different operations.

      <存储库>:定义类型必须执行的一组方法,以执行一组用例所需的数据相关任务。 通常,我们应该为每个模型使用一个存储库,使用泛型的单个存储库会很复杂,因此不建议这样做,因为每个模型可能需要不同的操作。
    • <ThirdPartyService>: Defines a set of methods a type must implement to use a third party service. Setting an interface for this means that we can swap the framework or library we use and don’t affect the app at all.

      <ThirdPartyService>:定义类型必须使用一组方法才能使用第三方服务。 为此设置接口意味着我们可以交换我们使用的框架或库,而完全不影响应用程序。

    Keep in mind that every module is plug and play. This allows modules to be shared between other modules or even across applications.

    请记住,每个模块都是即插即用的。 这允许模块在其他模块之间甚至在应用程序之间共享。

    模块提供者 (Module Provider)

    The Module Provider switches between a Feature module’s root navigation controller, on UIKit projects and rootView on SwiftUI projects. The switching is done through the activeModule attribute of type Module of the ModuleProvider class. The Module is just an enum with all the available module names. The switch could be done through a singleton or via NotificationCenter, this means that any module can tell the ModuleProvider that it’s time to switch to a new module or to dismiss itself to the root module.

    模块提供程序在UIKit项目上的功能模块的根导航控制器和SwiftUI项目上的rootView之间切换。 切换是通过ModuleProvider类的Module类型的activeModule属性完成的。 该模块只是具有所有可用模块名称的枚举。 切换可以通过单例完成,也可以通过NotificationCenter进行,这意味着任何模块都可以告知ModuleProvider,现在该切换到新模块或将自己退出到根模块了。

    It’s up to you to choose how to provide AppDelegate or SceneDelegate with the appropriate rootViewController or rootView respectively through the ModuleProvider, to avoid toying with Combine, DI and Singletons (more on that in a following post) the following implementation does the job.

    由您自己决定如何通过ModuleProvider为AppDelegate或SceneDelegate分别提供适当的rootViewController或rootView,以避免通过使用Combine,DI和Singletons(在下一篇文章中有更多介绍)来完成以下实现。

    Fig.9 Module Provider example
    图9模块提供者示例

    With that implementation you can send the notification to change a module from any ViewModel, Presenter or ViewController you need.

    通过该实现,您可以发送通知以从所需的任何ViewModel,Presenter或ViewController更改模块。

    整个图片 (The whole picture)

    Image for post
    Fig.10 Dependency diagram of a the whole architecture
    图10整个架构的依赖图

    翻译自: https://medium.com/swlh/my-journey-to-understanding-software-architecture-as-a-junior-ios-dev-5a819cc6716f

    ios 初级开发

    展开全文
  • 想做一个类似新闻内容页的View。可以像网页一下上下滚动浏览 我有图片和文字,放在一个scrollView里面,但是,完全不懂怎么让它自定义高度。要么部分文字看不到,要么定义view太高。 ... |--------TextView
  • ios初级笔记

    2015-08-13 00:35:10
    ios初级代码 1.oc中的set和get方法 1>.首先NewFile创建类,选iOS中的Cocoa Touch,再点击Objective-C class,输入类名Student,作为NSobject(系统 自带)的子类 2>.在.h中做方法的声明 在Student.h中: //@...
  • 如题,初级初级初级初级~ 1.在UITableView中,我们的Cell可能会有一些前置显示的图标,可能有很多个类型的图标,我们应该维护一个图标的array,而不是每次加载cell的时候通过UIImage去生成一个图标。

    开始学习iOS内存优化,从最开始的学起,记录一些平时大家都可能会用到的技巧。如题,初级初级初级初级~


    1.在UITableView中,我们的Cell可能会有一些前置显示的图标,可能有很多个类型的图标,我们应该维护一个图标的array,而不是每次加载cell的时候通过UIImage去生成一个图标。

    展开全文
  • Gezbox ios 初级笔试题

    2013-04-22 11:00:44
    Gezbox ios 初级笔试题
  • ios 初级入门学习

    2021-07-08 20:29:16
    ios 初级入门学习 学习第一天 ##工程基础 **objective-c 基础知识 ...

    ios 初级入门学习

    学习第一天

    ##工程基础

    1. **objective-c 基础知识 https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40011210-CH1-SW1;
    2. iOS
    3. 跨平台
    4. 服务端
    5. 客户端
    6. 代码管理工具
    7. 形成自己的工具链
    8. 代码规范,编程习惯

    oc

    基础语法,类,元类,属性,block,协议,内存管理

    UIKit相关控件

    UIView,UIController,UINavigationController

    展开全文
  • iOS初级学习PDF

    2014-10-04 23:10:08
    很好的iOS学习文档,讲解很到位,我就是看这个学的
  • IOS初级UI代码

    2013-09-18 16:07:36
    初学了几个月的IOS,把UI初级部分总结了下,模拟了手机,内容,多次修改,有点乱,不过注释挺好,灰常适合初级的,(*^__^*) 嘻嘻……,给点分吧,穷啦
  • IOS开发 初级笔记

    2011-05-23 18:45:08
    ios开发的一些经验 和一些很使用的快捷键 适合初学者
  • ios应用开发初级指南

    2013-03-07 21:53:29
    ios应用开发指南初级篇,可以给初学者提供很好的学习资料,供爱好者学习
  • iOS初级面试题目

    2020-06-21 10:21:04
    从最基本的方法调用,到高级的runtime的应用都是属于Foundation框架的基础,这里我罗列下我所知道的关于Foundation基础在面试中经常被问到的问题,由于我自身能力有限,而且面试的主要是针对初级iOS开发所以问题含量...

    开篇

    又到了下一届学弟找工作的时候啦,最近我简单的询问了几个学弟的情况都不是很乐观,首先不可否认的时候现在的大环境就业确实是很难的,但是难也是相对而言的,我们要从自身去出发,发现自己的不足,是否是自己的学习闭环出了问题,又或者是我们的学习成果达不到对标的需求的岗位。

    学习方法

    首先简单的说下我的学习方法,因为主要是给学弟们看的,我也就不怕大家笑话,自告奋勇,不要脸的来做下分享。 首先学习的话要是有目标的,朝着目标不断的迭代递进,如果对于软件工程有了解的话,我觉得学习的过程就是一个敏捷开发scrum的一个迭代周期,简单的说就是行成一个闭环的学习,周期性的review,找到自己的缺陷,feed到下一个周期的学习中。不再多做赘述,因为我本身也不是很了解,而且自己也在不断的探索中。

    iOS基础知识

    iOS的基础知识的话在面试中也是经常被问到的,我总结出三个方面

    • C语言基础(掌握即可)
    • Foundation基础 (常见的掌握)
    • UIKit基础 (常见的布局,UI要会)

    c语言基础就不再多说了,因为我们现在面对的主要是应付面试,找到一个我们理想的工作。

    Foundation基础

    Foundation的基础支撑着整个iOS的开发,从最基本的方法调用,到高级的runtime的应用都是属于Foundation框架的基础,这里我罗列下我所知道的关于Foundation基础在面试中经常被问到的问题,由于我自身能力有限,而且面试的主要是针对初级iOS开发所以问题含量有限。

    • 关于属性关键字的运用 (strong,weak,copy…)
    • OC动态性的理解
    • runtime的理解
    • 内存管理
    • block的原理与block循环引用的解决
    • 多线程的应用
    • Runloop的应用

    UIkit基础

    • 常见UI布局
    • 自定义UI
    • 常见控件的运用

    网络基础

    • http与htpps区别
    • Tcp/IP 相关知识
    • 三次握手/四次挥手 目的
    • session/cookie的作用

    操作系统基础

    • 线程与进程区别
    • 银行家算法

    数据结构与算法基础

    • 基本的排序算法
    • leetcode经典题目

    其他

    • 设计模式的理解

    上面举得例子是我认为重点的,其他部分可以参考网上的面试题目,多多使用牛客,leetcode,来刷面试题,可以找学长进行一些内推操作。
    面试的重心放在iOS基础和数据结构与算法,因为时间原因和最近没有面试的经历,所以暂时想到这些,有不明白的可以及时来问我,我最近也会再补充题目。

    最后

    希望各位工作顺利,前程似锦。

    展开全文
  • ios block初级使用

    2014-12-26 20:15:24
    block和GCD是ios高级程序员面试必问的问题,ben'pi
  • IOS初级省市区

    2015-02-03 09:01:39
    本篇博客主要的内容是:ios省市区的项目,从导入文件开始,把文本文件都存在一个数组中,本次习题的目的,可以让我们利用可变数组和字典的结合,完成一个小项目! #import int main(int argc, ...
  • iOS 初级错误和警告汇总

    千次阅读 2016-04-13 17:13:22
    这是一篇适合初级开发者学习的文章, 总结了一些很初级的错误和警告.
  • 文件太大,我上传到百度云里了,下载连接即可,IOS进阶从初级到高级教程
  • 前言看完前面3章的内容,基本对IOS开发有一些...系列文章:IOS 初级开发入门教程(一)介绍篇IOS 初级开发入门教程(二)第一个HelloWorld工程及StoryBoard使用IOS 初级开发入门教程(三)探究应用及视图的生命周...
  • iOS初级面试总结(一)
  • iOS初级职位任务(MVVM) 连接: 电子邮件: 领英(LinkedIn) 项目实现时间表: 8小时: 初始MVVM文件结构 故事板视图 主VC 表格视图拉动刷新 获取帖子和用户详细信息API数据 显示数据 非React性本机值观察 主...
  • iOS初级教程(一)

    2017-01-17 23:29:52
    学习ios开发,首先要了解的是ios是什么 ios开发分为两部分:账号使用和代码编辑两部分 1、账号使用 在学习ios开发前首先了解ios账号的种类以及各个种类的功能以及作用。 可以参考苹果官网 ...
  • ios sqlite3 初级应用

    2012-03-12 11:41:00
    ios sqlite3 初级应用 在ios中,持久化用好几种 方法,前面已经介绍了 两种 ,一个是简单的写入文件,另一个是加入了序列化并写入文件中,现在介绍 ios 中嵌入式数据库sqlite3的初级应用 当然在使用...
  • 系列文章:IOS 初级开发入门教程(一)介绍篇IOS 初级开发入门教程(二)第一个HelloWorld工程及StoryBoard使用IOS 初级开发入门教程(三)探究应用及视图的生命周期变化IOS 初级开发入门教程(四)基础控件使用小...
  • IOS初级:SDWebImage

    2015-10-01 00:23:00
    简单用法 #import "ViewController.h" #import "SDWebImage/UIImageView+WebCache.h" ...@interface ViewController () ...@property (strong, nonatomic) IBOutlet UIImageView *img;...@implementation ...
  • IOS初级:AFNetworking

    2015-09-30 00:36:51
     iOS 8.2; Scale/2.00)"; } 2015-10-01 00:26:49.419 afnet[906:20954]  0x7a67bba0> { URL: http://demo.com/app/index.php/app_ios_0_1/userInfo?uid=1 } { status code: 200, headers {  ...
  • 这是关于IOS初级控件的一些Swift的示例代码,里面都有详细的注解,以及详细的属性解释
  • IOS初级:NSTimer

    2015-07-13 15:16:00
    @property (nonatomic, strong) NSTimer *timer; 添加定时器 self.timer = [NSTimer scheduledTimerWithTimeInterval:999.0 target:self selector:@selector(executeFun) userInfo:nil repeats:YES];...
  • - (IBAction)signOutAction:(id)sender { //初始化,StyleActionSheet是对话框的样式 UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"是否注销?" message:@"真的要注销吗" ...
  • IOS初级:NSKeyedArchiver

    2015-06-16 17:31:11
    NSKeyedArchiver对象归档

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,155
精华内容 4,062
关键字:

初级ios