- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
早期警告 - 代码示例有点长...
我有一个单例 NSMutableArray,可以从应用程序中的任何位置访问它。我希望能够引用NSMutableArray
来自多个 NIB 文件,但通过 NSArrayController
绑定(bind)到 UI 元素对象。初始创建不是问题。我可以引用单例NSMutableArray
当 NIB 被加载并且一切看起来都很好时。
但是,更改 NSMutableArray
通过添加或删除对象不会启动 KVO 来更新NSArrayController
实例。我意识到“在 Controller 背后进行更改”被认为是 Cocoa-land 的禁忌部分,但我没有看到任何其他方式以编程方式更新 NSMutableArray
并让每个NSArrayController
收到通知(当然它不起作用......)。
我在下面简化了类(class)来解释。
简化的单例类 header :
@interface MyGlobals : NSObject {
NSMutableArray * globalArray;
}
@property (nonatomic, retain) NSMutableArray * globalArray;
简化的单例方法:
static MyGlobals *sharedMyGlobals = nil;
@implementation MyGlobals
@synthesize globalArray;
+(MyGlobals*)sharedDataManager {
@synchronized(self) {
if (sharedMyGlobals == nil)
[[[self alloc] init] autorelease];
}
return sharedMyGlobals;
}
-(id) init {
if(self = [super init]) {
self.globals = [[NSMutableArray alloc] init];
}
return self
}
// ---- allocWithZone, copyWithZone etc clipped from example ----
在这个简化的示例中,数组中对象的 header 和模型:
头文件:
@interface MyModel : NSObject {
NSInteger myId;
NSString * myName;
}
@property (readwrite) NSInteger myId;
@property (readwrite, copy) NSString * myName;
-(id)initWithObjectId:(NSInteger)newId objectName:(NSString *)newName;
@end
方法文件:
@implementation MyModel
@synthesize myId;
@synthesize myName;
-(id)init {
[super init];
myName = @"New Object Name";
myId = 0;
return self;
}
@end
现在想象两个带有适当 NSArrayController
的 NIB 文件实例。我们称它们为myArrayControllerInNibOne
和myArrayControllerInNib2
。 init
中的每个阵列 Controller NIB Controller 的设置数组的内容:
// In NIB one init
[myArrayControllerInNibOne setContent: [[MyGlobals sharedMyGlobals].globalArray];
// In NIB two init
[myArrayControllerInNibTwo setContent: [[MyGlobals sharedMyGlobals].globalArray];
当每个NIB初始化NSArrayController
时正确绑定(bind)到共享数组,我可以按照您的预期在 UI 中看到数组内容。我有一个单独的后台线程,当内容根据外部事件发生变化时,它会更新全局数组。当需要在此后台线程中添加对象时,我只需将它们添加到数组中,如下所示:
[[[MyGlobals sharedMyGlobals].globalArray] addObject:theNewObject];
这就是事情崩溃的地方。我无法调用willChangeValueForKey
和didChangeValueForKey
在全局数组上,因为共享实例没有键值(我应该在单例类中添加它吗?)
我可以发射一个NSNotification
并在 NIB Controller 中捕获它,然后执行 [myArrayControllerInNibOne rearrangeObjects]
;或者将内容设置为nil
并将内容重新分配给数组 - 但这两者看起来都像是黑客和。此外,设置 NSArrayController
至nil
然后返回全局数组,当内容被清除并重新填充时,会导致 UI 内出现视觉闪烁。
我知道我可以直接添加到 NSArrayController
并且数组得到更新,但我没有看到 a) 其他 NSArrayController
如何实例将被更新,并且 b) 我不想将我的后台线程类显式绑定(bind)到 NIB 实例(我也不应该这样做)。
我认为正确的方法是在addObject
周围以某种方式触发KVO通知。在后台线程中,或者向存储在全局数组中的对象添加一些内容。但我却不知所措。
需要注意的是,我没有使用 Core Data。
任何帮助或协助将不胜感激。
最佳答案
预警 - 回答有点长......
使用对您的域进行建模的对象。您不需要单例或全局变量,您需要常规类的常规实例。您的全局数组中存储了哪些对象?创建一个代表模型的该部分的类。
如果您使用 NSMutableArray 作为存储,它应该位于您的类的内部,并且对外部对象不可见。例如,如果您正在建模动物园,请不要这样做
[[[MyGlobals sharedMyGlobals].globalArray] addObject:tomTheZebra];
做做
[doc addAnimal:tomTheZebra];
不要尝试观察可变数组 - 您想观察对象的多对多属性。例如。而不是
[[[MyGlobals sharedMyGlobals].globalArray] addObserver:_controller]
你想要
[doc addObserver:_controller forKeyPath:@"animals" options:0 context:nil];
其中 doc 对于多对多属性“anaimals”符合 kvo 要求。
要使 doc kvo 兼容,您需要实现这些方法(注意 - 您不需要所有这些方法。有些是可选的,但性能更好)
- (NSArray *)animals;
- (NSUInteger)countOfAnimals;
- (id)objectInAnimalsAtIndex:(NSUInteger)i;
- (id)AnimalsAtIndexes:(NSIndexSet *)ix;
- (void)insertObject:(id)val inAnimalsAtIndex:(NSUInteger)i;
- (void)insertAnimals:atIndexes:(NSIndexSet *)ix;
- (void)removeObjectFromAnimalsAtIndex:(NSUInteger)i;
- (void)removeAnimalsAtIndexes:(NSIndexSet *)ix;
- (void)replaceObjectInAnimalsAtIndex:(NSUInteger)i withObject:(id)val;
- (void)replaceAnimalsAtIndexes:(NSIndexSet *)ix withAnimals:(NSArray *)vals;
好吧,这看起来很吓人,但也没那么糟糕,就像我说的,你并不需要它们全部。 See here 。这些方法不需要成为模型接口(interface)的一部分,您只需添加:-
- (void)addAnimal:(id)val;
- (void)removeAnimal:(id)val;
并根据 kvc 访问器编写它们。关键点是,数组不是在更改时发送通知的,数组只是幕后的存储,是模型类发送对象已添加或删除的通知。
您可能需要重组您的应用。您可能需要完全忘记 NSArrayController。
Aaaaaannnnnyyywaaayyy…如果你这样做,所有这些都不会给你带来任何好处
[[[MyGlobals sharedMyGlobals].globalArray] addObject:theNewObject];
或者这个[doc addAnimal:tomTheZebra];
来自后台线程。你不能这样做。 NSMutableArray 不是线程安全的。如果它看起来有效,那么最好的情况是 kvo/绑定(bind)通知也在后台传递,这意味着您将尝试在后台更新 GUI,但您绝对不能这样做。恐怕使数组静态没有任何帮助 - 您必须为此想出一个策略..最简单的方法是 performSelectorOnMainThread
但除此之外完全是另一个问题。线程很难。
关于那个静态数组——停止使用静态,你不需要它。不是因为你有 2 个 Nib 、2 个窗口或任何东西。你有一个代表你的模型的实例,并将指向该模型的指针传递给你的 View Controller 、窗口 Controller 等。没有单例/静态变量对测试有很大帮助,当然你应该这样做。
关于objective-c - NSArrayController 在多个 NIB 中访问单例 NSMutableArray,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3113974/
我正在尝试在手写笔中使用 Nib CSS3 扩展。安装了手写笔和 Nib (尝试了本地和全局 -g)。但没有一个工作,当我做 stylus styles.styl > build/styles.css
我们当前的best-practice for custom views是: 在 Nib 中构建自定义 View 。 在 View Controller 中,以编程方式加载 Nib,从加载的对象数组中获
我是界面构建器的新手,我想要一个包含 UIView 的 3x3 网格的屏幕,每个网格都包含一个 UIImageView 和 4 个 UILabels。 我的逻辑可能有缺陷,但我试图实现这一目标的方式是
我有一个用 Swift 编写的框架/模块,它提供了一些具有 IBDesignable 功能的自定义控件。 目前我正在开发一个基于 CollectionView 的控件。 CollectionView
我有两个 nib 文件 - Main.nib 和 Preference.nib在 Main.nib 文件中,我有一个 NSView 类的实例。它的窗口有一个NSPopUpButton,单击它会显示一个
我想创建一个节标题来加载一个 nib 文件并将其设置为标题 UIView。这个 nib 文件还将有一个关联的类,其中连接了 outlets 和 action,所以我想像平常一样用 nib 加载那个类。
我正在尝试使用来自 this pre-built page menu pod from github 在说明中,它说: var controller : UIViewController =
我是 Cocoa 新手,无法将我的 nib 文件拆分为多个 nib 文件。 我的MainMenu.nib包含一个Tracker Controller对象,它是NSObject的子类。它在我的主菜单中有
我通过 XIB 创建了 CustomViewController。 我还通过作为 UIView 子类的不同 XIB 文件创建了 CustomView。 然后我将 UIView 绑定(bind)到 Cu
我正在使用自定义 UITableViewCell。当我尝试运行我的代码时,我得到了这个异常堆栈,我无法理解问题的根源: terminating app due to uncaught exceptio
我有两个 Nib ParentViewController.xib ChildViewController.xib ParentViewController.xib 包含一个 UIView 和一个 U
我一开始使用了一些 NSWindows 项目,但我的 GUI 正在不断发展,这些元素将更适合作为 NSViews。有没有办法将 NSWindow NIB 转换为 NSView NIB? 最佳答案 不存
我想要具有正确顺序的 View Controller 生命周期功能的完整列表。请任何天才。 请指定ViewController生命周期函数. 请指定序列号,例如用法:,并且仅使用简短描述。示例: 与使
我有两个 Nib :Parent.xib 和 Child.xib。 我已将子 Nib 包含在父 Nib 内以简化绑定(bind)。我在 loadView 中以编程方式设置 subview 。问题是,a
我正在开发一款通用应用程序,iPhone 版本运行良好。我为 iPad 创建了一个新的 nib,并将文件所有者设置为 viewcontroller 类。我连接了所有的 IBOutlets 和 IBAc
我有两个 UIViews,我将它们称为 A 和 B。 A 是B 的容器,每一个都是使用Interface Builder 创建的。 我需要使用界面生成器将我的 B View 添加到 A 中,如下图所示
谁能解释什么时候对同一个 NIB 文件使用多个 View 比使用多个 NIB 文件更好? 一个 NIB 文件可以包含多个 View ,因此有时使用一种方法比使用另一种方法更好。 我是不是太含糊了? 最
简单的任务:我有一个带有 2 个 NIB 文件的应用程序(每个 NIB 文件都有自己的 Controller )。我已经成功地显示了第二个 NIB 文件的窗口,就像我想要的那样,但现在,我想单击 NI
目前,我有一个托管上下文、许多相互关联的实体 NSArrayController,以及几个 Windows,每个 Windows 都使用 1 或 2 个 NSArrayController。 Wind
尝试创建一个 tableView 单元格 xib,但遇到错误“加载了 nib 但未设置 View 导出” 我读过很多帖子,大多数人都说将“ View ”从文件所有者拖到 IB View 。 但是,如果
我是一名优秀的程序员,十分优秀!