小编Nic*_* B.的帖子

UIViewController扩展来从storyboard实例化

我正在尝试在Swift中编写一个小扩展来处理UIViewController故事板中的实例化.

我的想法如下:由于UIStoryboard方法instantiateViewControllerWithIdentifier需要一个标识符来实例化给定的故事板的视图控制器,为什么不在我的故事板中为每个视图控制器分配一个等于其确切类名UserDetailViewController的标识符(即,将具有"UserDetailViewController"的标识符) "),并在UIViewController上创建一个类方法:

  • 接受UIStoryboard实例作为唯一参数
  • 将当前类名称作为字符串
  • instantiateViewControllerWithIdentifier使用类名作为参数调用storyboard实例
  • 获取新创建的UIViewController实例,然后返回它

所以,而不是(将类名重复为字符串,不是很好)

let vc = self.storyboard?.instantiateViewControllerWithIdentifier("UserDetailViewController") as UserDetailViewController
Run Code Online (Sandbox Code Playgroud)

这将是:

let vc = UserDetailViewController.instantiateFromStoryboard(self.storyboard!)
Run Code Online (Sandbox Code Playgroud)

我曾经在Objective-C中使用以下类别:

+ (instancetype)instantiateFromStoryboard:(UIStoryboard *)storyboard
{
    return [storyboard instantiateViewControllerWithIdentifier:NSStringFromClass([self class])];
}
Run Code Online (Sandbox Code Playgroud)

但我完全坚持使用Swift版本.我希望有某种方法可以做到这一点.我尝试了以下方法:

extension UIViewController {
    class func instantiateFromStoryboard(storyboard: UIStoryboard) -> Self {
        return storyboard.instantiateViewControllerWithIdentifier(NSStringFromClass(Self))
    }
}
Run Code Online (Sandbox Code Playgroud)

返回Self而不是AnyObject允许类型推断工作.否则,我将不得不抛出这种方法的每一次返回,这很烦人,但也许你有更好的解决方案?

这给我的错误:Use of unresolved identifier 'Self'NSStringFromClass部分似乎是问题.

你怎么看?

  • 有没有办法Self从课程功能返回?

  • 如果不需要每次都抛出返回值,你将如何工作?(即保持-> Self为返回值)

谢谢.

iphone objective-c uiviewcontroller ios swift

11
推荐指数
3
解决办法
7957
查看次数

OpenGL ES不会删除内存中的纹理

我目前正在开发一个使用OpenGL ES 1.0渲染一些基本纹理的iOS应用程序(iPad和iPhone).我使用地图集来存储和呈现我的纹理.

我的主要图集相对较大(2000x2000)但我的内部算法加载并将纹理大小调整为2048x2048,因为OpenGL ES只接受2个大小纹理的功能.我能够画出瓷砖,这一切都很好.

每当我尝试加载和卸载(破坏)纹理时,我都会面临严重的内存泄漏.这应该发生在最终版本中,但我需要确保我的装载和卸载都很好.在内存中,纹理占用2048x2048x4(RGBA)字节=约16MB.这是一个巨大的字节数,所以你明白这个问题对我来说很烦人(几分钟后iOS就会杀死它.)

当我加载纹理时,Instruments表示应用程序使用的总内存增加了16MB,这是正确的(我使用"Real Memory"列).当我需要销毁纹理以释放它所使用的所有可能字节时,问题就出现了:它永远不会丢失16MB ......而且由于我在循环中加载和卸载,因此内存不断被使用而且从未被释放.

这是我加载纹理的方法:

GLubyte *outData = malloc((_dataWidth * _dataHeight * 4) * sizeof(*outData));
GLuint _texture; // declared as un instance variable so its address never changes
glGenTextures(1, &_texture);
glBindTexture(GL_TEXTURE_2D, _texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _dataWidth, _dataHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, outData);
free(outData);
Run Code Online (Sandbox Code Playgroud)

这是我卸载纹理的方法(这个叫做,我查了一下)

glDeleteTextures(1, &_texture);
Run Code Online (Sandbox Code Playgroud)

我到处使用glGetError()来检查是否发生了错误,但它总是返回0(即使在glDeleteTexture之后).

有人有想法吗?谢谢!

iphone textures memory-leaks opengl-es ios

6
推荐指数
1
解决办法
5109
查看次数

为什么UIViewController的'view'属性在Swift中不是可选的?

我注意到view属性UIViewController不是类型UIView?,UIView而是(即不是可选的).这是为什么?是不是UIViewController的视图应该是nil什么时候没有加载?

官方文档说明如下:

存储在此属性中的视图表示视图控制器的视图层次结构的根视图.此属性的默认值为nil.....在低内存条件下以及最终释放视图控制器本身时,UIViewController类可以自动将此属性设置为nil.

根据我对Swift选项的理解,似乎view应该声明,var view: UIView?因为它可能nil在某个时候.Apple似乎反过来说,你能解释一下我的原因吗?

你怎么看?

iphone uiviewcontroller uiview ios swift

6
推荐指数
1
解决办法
1033
查看次数

在Swift中声明标量值列表的最佳方法是什么?

我想知道:在Swift中声明一个非有序的标量值列表的最佳方法是什么,它们完全由符号支持并且易于被编译器检查?

假设我想声明一个LetterSpacing值列表,我希望通过符号来访问和使用我的代码.

我的理解是我应该enum像这样迅速宣布:

enum LetterSpacing: Double {
    case Short = 1.0
    case Medium = 2.0
    case Large = 3.0
}
Run Code Online (Sandbox Code Playgroud)

这工作正常,并获得编译器检查,但令人讨厌的部分是我LetterSpacing.XXX.rawValue每次都需要访问基础值.在.rawValue困扰我有点不得不到处指定.

我认为struct用三等声明是没有意义或不合适的static let Short = 1.0.

那么,你会如何处理这类案件?是否有可能为现有类型添加一些协议/扩展swift魔法,以便能够将Short枚举作为自己的值?(let size = LetterSpacing.Short即将是类型Double并具有值1.0)

swift

6
推荐指数
1
解决办法
141
查看次数

Swift 2.0中的协议扩展方法调度

我正面临协议方法调度的问题.

我有一个类层次结构,看起来像这样:

protocol E {
    func test()
}

extension E {
    func test() {
        print("jello")
    }
}

class A: E {

}

class B: A {
    func test() {
        print("hello")
    }
}
Run Code Online (Sandbox Code Playgroud)

但是当我打电话给静态强制输入test类的实例时,"jello"被打印出来,而不是"你好".BA

let b: A = B()  // prints "jello" not "hello"
b.test()
Run Code Online (Sandbox Code Playgroud)

我的理解是test方法打印"jello"被"集成"到A(因为A符合E协议)的实例中.然后我提供另一个test内部实现B(继承表单A).我以为多态性会在这里工作,并呼吁testB实例存储内A引用将打印hello.这里发生了什么事?

不使用任何协议时,它完美地工作:

class A {
    func test() {
        print("jello")
    } …
Run Code Online (Sandbox Code Playgroud)

polymorphism xcode ios swift xcode7

6
推荐指数
1
解决办法
274
查看次数

返回一个 Self 类型的数组

我无法找出一种在 Swift 中在运行时返回特定动态类类型的实例数组的方法。

我成功编译并测试了这个版本,它返回一个类的单个实例:

class Generic {

    class func all() -> Self {
        return self.init()
    }

    required init() {

    }

}

class A: Generic {

}

let a = A.all() // is of type A
Run Code Online (Sandbox Code Playgroud)

这里的挑战是进行编译以允许all函数原型如下:(class func all() -> [Self]即返回一个实例数组,使用子类,没有任何 cast)。

class Generic {

    class func all() -> [Self] {
        return [self.init()]
    }

    required init() {

    }

}

class A: Generic {

}

let a = A.all() // won't compile
Run Code Online (Sandbox Code Playgroud)

我可以Generic使用 with返回一个实例数组, …

ios swift

5
推荐指数
1
解决办法
1269
查看次数